QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#44318#4604. Shattrath CityGemini7XAC ✓782ms11948kbC++202.5kb2022-08-15 15:53:332022-08-15 15:53:35

Judging History

This is the latest submission verdict.

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-08-15 15:53:35]
  • Judged
  • Verdict: AC
  • Time: 782ms
  • Memory: 11948kb
  • [2022-08-15 15:53:33]
  • Submitted

answer

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+5,mod=998244353;
int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
int dec(int a,int b){return a<b?a-b+mod:a-b;}
int mul(int a,int b){return 1ll*a*b%mod;}
int ksm(int a,int b=mod-2){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;}
int F[maxn],G[maxn],fac[maxn],ifac[maxn];
int gn[maxn],rev[maxn];
int N,M;
void initg(int len){
    for(int i=1;i<len;i<<=1){
        gn[i]=1;
        gn[i+1]=ksm(3,(mod-1)/(i<<1));
        for(int j=2;j<i;j++){
            gn[i+j]=mul(gn[i+j-1],gn[i+1]);
        }
    }
}
void ntt(int *f,int len,int op){
    for(int i=0;i<len;i++)if(i<rev[i])swap(f[i],f[rev[i]]);
    for(int i=1;i<len;i<<=1){
        for(int j=0;j<len;j+=i<<1){
            for(int k=0;k<i;k++){
                int x=f[j+k],y=mul(gn[i+k],f[j+k+i]);
                f[j+k]=add(x,y);
                f[j+k+i]=dec(x,y);
            }
        }
    }
    if(op==-1){
        int Inv=ksm(len);
        reverse(f+1,f+len);
        for(int i=0;i<len;i++)f[i]=mul(f[i],Inv);
    }
}
void poly_mul(int *f,int *g,int *h,int n,int m){
    static int a[maxn],b[maxn];
    int len=1,lg=0;
    while(len<=n+m)len<<=1,lg++;
    initg(len);
    for(int i=0;i<len;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
    for(int i=0;i<len;i++)a[i]=i<=n?f[i]:0;
    for(int i=0;i<len;i++)b[i]=i<=m?g[i]:0;
    ntt(a,len,1);ntt(b,len,1);
    for(int i=0;i<len;i++)a[i]=mul(a[i],b[i]);
    ntt(a,len,-1);
    for(int i=0;i<len;i++)h[i]=i<=n+m?a[i]:0;
}
void cdq(int l,int r){
    if(l==r){
        G[l]=mul(add(F[l-1],G[l-1]),N);
        if(l>=N)F[l]=dec(F[l],mul(add(F[l-N],G[l-N]),fac[N]));
        return;
    }
    int mid=(l+r)>>1;
    cdq(l,mid);
    static int A[maxn],B[maxn],C[maxn];
    for(int i=l;i<=mid;i++)A[i-l]=F[i];
    for(int i=1;i<=min(N-1,r-l);i++)B[i]=fac[i];
    poly_mul(A,B,C,mid-l,min(N-1,r-l));
    for(int i=mid+1;i<=min(mid+min(N-1,r-l),r);i++)F[i]=dec(F[i],C[i-l]);
    cdq(mid+1,r);
}
void MAIN(){
    scanf("%d%d",&N,&M);
    //N=100000,M=200000; 
    F[0]=0;G[0]=1;
    for(int i=1;i<=M;i++)F[i]=G[i]=0;
    fac[0]=1;
    for(int i=1;i<N;i++){
    	fac[i]=mul(fac[i-1],i);
    	G[i]=mul(G[i-1],N);
	}
	fac[N]=mul(fac[N-1],N);
    cdq(N,M);
    printf("%d\n",add(F[M],G[M]));
}
void init(int mx){
    fac[0]=ifac[0]=1;
    for(int i=1;i<=mx;i++)fac[i]=mul(fac[i-1],i);
    ifac[mx]=ksm(fac[mx]);
    for(int i=mx-1;i;i--)ifac[i]=mul(ifac[i+1],i+1);
}
int main(){
    int T;scanf("%d",&T);while(T--)MAIN();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 782ms
memory: 11948kb

input:

4
99999 199996
44353 200000
41592 199824
192608 199978

output:

425744116
51535034
430216206
653776337

result:

ok 4 lines