QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#121685#6410. Classical DP ProblemSolitaryDream#WA 0ms40536kbC++206.1kb2023-07-08 17:40:002023-07-08 17:40:01

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-08 17:40:01]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:40536kb
  • [2023-07-08 17:40:00]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;

#define int long long

const int N=1e6+1e3+7,P=998244353,g=3;

int qpow(int a,int b)
{
    int ret=1;
    while(b)
    {
        if(b&1)
            ret=1ll*ret*a%P;
        b>>=1;
        a=1ll*a*a%P;
    }
    return ret;
}

int n,a[N],b[N];

int fac[N],inv[N];

void dft(int *a,int n,int f)
{
    static int rev[N],ww[N],iw[N],pn=0;
    if(pn!=n)
    {
        int p=qpow(g,(P-1)/n);
        ww[0]=1;
        for(int i=1;i<=n-1;i++)
            ww[i]=ww[i-1]*p%P;
        iw[n-1]=qpow(ww[n-1],P-2);
        for(int i=n-1;i>=1;i--)
            iw[i-1]=iw[i]*p%P;
        for(int i=0;i<n;i++)
            rev[i]=(rev[i>>1]>>1)|((i&1)*(n>>1));
        pn=n;
    }
    int *w=f>0?ww:iw;
    for(int i=0;i<n;i++)
        if(rev[i]<i)
            swap(a[rev[i]],a[i]);
    for(int l=2;l<=n;l<<=1)
        for(int *p=a;p!=a+n;p+=l)
            for(int i=0,m=l>>1;i<m;i++)
            {
                int t=p[i+m];
                p[i+m]=(p[i]+w[n/l*(i+m)]*t)%P;
                p[i]=(p[i]+w[n/l*i]*t)%P;
            }
    if(f<0)
    {
        int t=qpow(n,P-2);
        for(int i=0;i<n;i++)
            a[i]=a[i]*t%P;
    }
}

void Poly_Mul(const int *A,int LenA,const int *B,int LenB,int *C)
{
    static int a[N],b[N];
    int n=1;for(;n<LenA+LenB;n<<=1);
    for(int i=0;i<n;i++)
        a[i]=b[i]=0;
    for(int i=0;i<LenA;i++)
        a[i]=A[i];
    for(int i=0;i<LenB;i++)
        b[i]=B[i];
    dft(a,n,1);
    dft(b,n,1);
    for(int i=0;i<n;i++)
        C[i]=a[i]*b[i]%P;
    dft(C,n,-1);
}

void Poly_Inv(const int *A,int LenA,int *B)
{
    static int a[N],b[N];
    B[0]=qpow(A[0],P-2);
    for(int l=2;(l>>1)<LenA;l<<=1)
    {
        int n=l<<1;
        for(int i=0;i<n;i++)
            a[i]=b[i]=0;
        for(int i=l>>1;i<l;i++)
            B[i]=0;
        for(int i=0;i<(l>>1)-1;i++)
            a[i]=B[i];
        for(int i=0;i<l;i++)
            b[i]=A[i];
        dft(a,n,1),dft(b,n,1);
        for(int i=0;i<n;i++)
            a[i]=a[i]*a[i]%P*b[i]%P;
        dft(a,n,-1);
        for(int i=0;i<l;i++)
            b[i]=((b[i]<<1)-a[i])%P;
    }
}

void Poly_Div(const int *A,int LenA,const int *B,int LenB,int *C,int *D)
{
    static int a[N],b[N],c[N];
    if(LenA<LenB)
    {
        for(int i=0;i<LenA;i++)
            D[i]=A[i];
        return;
    }
    int l=LenA-LenB+1;
    for(int i=0;i<l;i++)
        a[i]=b[i]=c[i]=0;
    for(int i=0;i<LenA;i++)
        a[i]=A[LenA-1-i];
    for(int i=0;i<LenB;i++)
        b[i]=B[LenB-1-i];
    Poly_Inv(b,l,c);
    Poly_Mul(a,l,c,l,b);
    for(int i=0;i<l;i++)
        C[i]=b[l-1-i];
    Poly_Mul(B,LenB,C,l,a);
    for(int i=0;i<LenB-1;i++)
        D[i]=(A[i]-a[i]+P)%P;
}

namespace Evaluation{
    const int V=N*30;
    int a[N],b[N],c[N],d[N];
    int mem[V],*loc;
    int *g[N<<1],*h[N<<1];
    void init(int L,int R,int p)
    {
        if(L==R)
        {
            g[p]=loc;
            loc+=2;
            g[p][0]=-b[L];
            g[p][1]=1;
            return;
        }
        int mid=(L+R)>>1;
        init(L,mid,p<<1);
        init(mid+1,R,p<<1|1);
        g[p]=loc;
        loc+=R-L+2;
        Poly_Mul(g[p<<1],mid-L+2,g[p<<1|1],R-mid+1,g[p]);
    }
    void calc(int L,int R,int p)
    {
        if(L==R)
        {
            c[L]=h[p][0];
            return;
        }
        int mid=(L+R)>>1;
        h[p<<1]=loc;
        loc+=mid-L+1;
        Poly_Div(h[p],R-L+1,g[p<<1],mid-L+2,d,h[p<<1]);
        calc(L,mid,p<<1);

        h[p<<1|1]=loc;
        loc+=R-mid;
        Poly_Div(h[p],R-L+1,g[p<<1|1],R-mid+1,d,h[p<<1|1]);
        calc(mid+1,R,p<<1|1);
    }
    void solve(const int *A,int n,const int *B,int m,int *C)
    {
        loc=mem;
        for(int i=0;i<n;i++)
            a[i]=A[i];
        for(int i=0;i<m;i++)
            b[i]=B[i];
        init(0,m-1,1);
        h[1]=loc;
        loc+=m;
        for(int i=0;i<m;i++)
            h[1][i]=0;
        Poly_Div(a,n,g[1],m+1,d,h[1]);
        calc(0,m-1,1);
        for(int i=0;i<m;i++)
            C[i]=(c[i]+P)%P;
    }
}

int k;

int calc(int *a,int x)
{
    int ret=1;
    for(int i=1;i<=k;i++)
        ret=1ll*ret*(a[i]-x)%P;
    return ret;
}

int A[N],B[N],tmp[N];

using poly=vector<int>;

poly solve(int l,int r)
{
    if(l==r)
    {
        return {P-1,A[l]};
    }
    int mid=(l+r)>>1;
    auto a=solve(l,mid);
    auto b=solve(mid+1,r);
    Poly_Mul(a.data(),a.size(),b.data(),b.size(),tmp);
    poly ret;
    for(int i=0;i<a.size()+b.size()-1;i++)
        ret.push_back(tmp[i]);
    return ret;
}

int val[N];

signed main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    reverse(a+1,a+n+1);
    for(int i=1;i<=n;i++)
        b[a[i]]++;
    for(int i=n;i>=1;i--)
        b[i]+=b[i+1];
    k=1;
    for(int i=2;i<=n+1;i++)
        if(a[i]<i||b[i]<i)
        {
            k=i-1;
            break;
        }
    int ans=0;
    fac[0]=1;
    for(int i=1;i<=k;i++)
        fac[i]=1ll*fac[i-1]*i%P;
    inv[k]=qpow(fac[k],P-2);
    for(int i=k-1;i>=0;i--)
        inv[i]=1ll*inv[i+1]*(i+1)%P;
    // int t=a[k+1];
    // for(int i=0;i<=t;i++)
    //     ans=(ans+1ll*(i&1?P-1:1)*fac[t]%P*inv[i]%P*inv[t-i]%P*calc(a,i))%P;
    int t=a[k+1];
    for(int i=1;i<=t;i++)
        A[i]=a[i];
    auto res=solve(1,t);
    vector<int>x(t+1);
    for(int i=0;i<=t;i++)
        x[i]=i;
    Evaluation::solve(res.data(),res.size(),x.data(),x.size(),val);
    for(int i=0;i<=t;i++)
        ans=(ans+1ll*(i&1?P-1:1)*fac[t]%P*inv[i]%P*inv[t-i]%P*val[i])%P;

    // t=b[k+1];
    // for(int i=0;i<=t;i++)
    //     ans=(ans+1ll*(i&1?P-1:1)*fac[t]%P*inv[i]%P*inv[t-i]%P*calc(b,i))%P;
    t=b[k+1];
    for(int i=1;i<=t;i++)
        A[i]=b[i];
    res=solve(1,t);
    x.clear();
    x.resize(t+1);
    for(int i=0;i<=t;i++)
        x[i]=i;
    Evaluation::solve(res.data(),res.size(),x.data(),x.size(),val);
    for(int i=0;i<=t;i++)
        ans=(ans+1ll*(i&1?P-1:1)*fac[t]%P*inv[i]%P*inv[t-i]%P*val[i])%P;
    ans=(ans-fac[k]+P)%P;
    printf("%lld %lld\n",k,ans);
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 40536kb

input:

3
1 2 3

output:

2 998244345

result:

wrong answer 2nd numbers differ - expected: '6', found: '998244345'