退役彩笔求助

P4389 付公主的背包

```cpp #pragma GCC optimize("Ofast") #include<bits/stdc++.h> #define MAXN 500005 #define reg register #define inl inline #define int long long #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) char buf[1<<21],*p1=buf,*p2=buf; //char sr[1<<21],z[20]; //int CC=-1,Z; using namespace std; const int Mod=998244353,Gi=3; int n,m,s[MAXN],lim,maxn,rev[MAXN],f[MAXN],g[MAXN],ans[MAXN],B[MAXN],C[MAXN],D[MAXN],E[MAXN],H[MAXN],Inv[MAXN]; inl int Read() { reg int x=0,fu=1; reg char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') fu=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-48; return x*fu; } /*inl void Ot() { fwrite(sr,1,CC+1,stdout); CC=-1; } inl void Print(int x,char chr='\n') { if(CC>1<<20) Ot(); if(x<0) { sr[++CC]='-'; x=-x; } while(z[++Z]=x%10+48,x/=10); while(sr[++CC]=z[Z],--Z); sr[++CC]=chr; }*/ inl int Pow(reg int x,reg int y) { reg int res=1; for(;y;y>>=1,x=x*x%Mod) if(y&1) res=res*x%Mod; return res; } inl void NTT(reg int *A,reg int opt)// A { for(reg int i=0;i<lim;i++) if(i<rev[i]) swap(A[i],A[rev[i]]); for(reg int mid=1;mid<lim;mid<<=1) { reg int Wn=Pow(Gi,(Mod-1)/(mid<<1)); for(reg int j=0;j<lim;j+=(mid<<1)) { reg int W=1; for(reg int k=0;k<mid;k++,W=W*Wn%Mod) { reg int x=A[j+k],y=W*A[j+k+mid]%Mod; A[j+k]=(x+y)%Mod; A[j+k+mid]=(x-y+Mod)%Mod; } } } if(opt==1) return; reverse(A+1,A+lim); reg int inv=Pow(lim,Mod-2); for(reg int i=0;i<lim;i++) A[i]=A[i]*inv%Mod; } void GetInv(reg int *F,reg int *G,reg int len)// C { if(len==1) return G[0]=Pow(F[0],Mod-2),void(); GetInv(F,G,(len+1)>>1); lim=1; maxn=0; while(lim<=(len<<1)) { lim<<=1; maxn++; } for(reg int i=1;i<lim;i++) rev[i]=((rev[i>>1]>>1)|((i&1)<<(maxn-1))); for(reg int i=0;i<len;i++) C[i]=F[i]; for(reg int i=len;i<lim;i++) C[i]=0; NTT(C,1); NTT(G,1); for(reg int i=0;i<lim;i++) G[i]=((2ll-G[i]*C[i]%Mod)+Mod)%Mod*G[i]%Mod; NTT(G,-1); for(reg int i=len;i<lim;i++) G[i]=0; } inl void GetDev(reg int *F,reg int *G,reg int len) { for(reg int i=1;i<len;i++) G[i-1]=F[i]*i%Mod; G[len-1]=0; } inl void GetInt(reg int *F,reg int *G,reg int len) { for(reg int i=1;i<len;i++) G[i]=F[i-1]*Pow(i,Mod-2)%Mod; G[0]=0; } inl void GetLn(reg int *F,reg int *G,reg int len)// B D { for(reg int i=0;i<(len<<1);i++) B[i]=D[i]=0; GetDev(F,B,len); GetInv(F,D,len); lim=1; maxn=0; while(lim<=(len<<1)) { lim<<=1; maxn++; } for(reg int i=1;i<lim;i++) rev[i]=((rev[i>>1]>>1)|((i&1)<<(maxn-1))); NTT(B,1); NTT(D,1); for(reg int i=0;i<lim;i++) B[i]=B[i]*D[i]%Mod; NTT(B,-1); GetInt(B,G,len); } void GetExp(reg int *F,reg int *G,reg int len)// E H { if(len==1) return G[0]=1,void(); GetExp(F,G,(len+1)>>1); lim=1; maxn=0; while(lim<=(len<<1)) { lim<<=1; maxn++; } for(reg int i=1;i<lim;i++) rev[i]=((rev[i>>1]>>1)|((i&1)<<(maxn-1))); for(reg int i=0;i<(len<<1);i++) E[i]=H[i]=0; GetLn(G,E,len); for(reg int i=0;i<len;i++) H[i]=F[i]; NTT(G,1); NTT(E,1); NTT(H,1); for(reg int i=0;i<lim;i++) G[i]=(1ll-E[i]+H[i]+Mod)*G[i]%Mod; NTT(G,-1); for(reg int i=len;i<lim;i++) G[i]=0; } signed main() { n=Read(); m=Read(); for(reg int i=1;i<=n;i++) s[Read()]++; reg int len=1; while(len<=m) len<<=1; Inv[0]=Inv[1]=1; for(reg int i=2;i<len;i++) Inv[i]=Inv[Mod%i]*(Mod-Mod/i)%Mod; for(reg int i=1;i<=m;i++) { if(s[i]) { for(reg int j=i;j<len;j+=i) f[j]=(f[j]+s[i]*(Mod-Inv[j/i])%Mod)%Mod; } } GetExp(f,g,len); GetInv(g,ans,len); for(reg int i=1;i<=m;i++) printf("%lld\n",ans[i]); return 0; } ```
by VenusM1nT @ 2019-11-30 09:27:31


@[Venus](/user/23243) 不会+Orz
by Karry5307 @ 2019-11-30 09:44:34


不会 + orz
by hater @ 2019-11-30 10:30:49


@[Venus](/user/23243) 最后为啥还要求逆,,直接提前处理出来不好吗
by NaCly_Fish @ 2019-11-30 16:01:53


@[NaCly_Fish](/user/115864) 试过了还是 wa 的说……
by VenusM1nT @ 2019-12-01 12:50:35


|