1. 程式人生 > >[BZOJ5306][HAOI2018]染色(容斥+FFT)

[BZOJ5306][HAOI2018]染色(容斥+FFT)

urn can blank lld ons out bool main define

https://www.cnblogs.com/zhoushuyu/p/9138251.html

註意如果一開始F(i)中內層式子中j枚舉的是除前i種顏色之外還有幾種出現S次的顏色,那麽後面式子就會難推很多。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 4 using namespace std;
 5 
 6 const int N=300010,M=10000010,mod=1004535809;
 7 int n,m,s,ans,w[N],fac[M],inv[M],rev[N],a[N],b[N];
8 9 int ksm(int a,int b){ 10 int res=1; 11 for (; b; a=1ll*a*a%mod,b>>=1) 12 if (b & 1) res=1ll*res*a%mod; 13 return res; 14 } 15 16 void NTT(int a[],int n,bool f){ 17 for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]); 18 for (int i=1; i<n; i<<=1
){ 19 int wn=ksm(3,f ? (mod-1)/(i<<1) : (mod-1)-(mod-1)/(i<<1)); 20 for (int p=i<<1,j=0; j<n; j+=p){ 21 int w=1; 22 for (int k=0; k<i; k++,w=1ll*w*wn%mod){ 23 int x=a[j+k],y=1ll*w*a[i+j+k]%mod; 24 a[j+k]=(x+y)%mod; a[i+j+k]=(x-y+mod)%mod;
25 } 26 } 27 } 28 if (f) return; 29 int inv=ksm(n,mod-2); 30 for (int i=0; i<n; i++) a[i]=1ll*a[i]*inv%mod; 31 } 32 33 int main(){ 34 freopen("color.in","r",stdin); 35 freopen("color.out","w",stdout); 36 scanf("%d%d%d",&n,&m,&s); int N=min(m,n/s),ed=max(n,m); 37 rep(i,0,m) scanf("%d",&w[i]); 38 fac[0]=1; rep(i,1,ed) fac[i]=1ll*fac[i-1]*i%mod; 39 inv[ed]=ksm(fac[ed],mod-2); 40 for (int i=ed-1; ~i; i--) inv[i]=1ll*inv[i+1]*(i+1)%mod; 41 rep(i,0,N) a[i]=1ll*w[i]*inv[i]%mod; 42 rep(i,0,N) b[i]=(i&1)?mod-inv[i]:inv[i]; 43 int nn=1,L=0; for (; nn<=2*N; nn<<=1,L++); 44 for (int i=0; i<nn; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1)); 45 NTT(a,nn,1); NTT(b,nn,1); 46 for (int i=0; i<nn; i++) a[i]=1ll*a[i]*b[i]%mod; 47 NTT(a,nn,0); 48 rep(i,0,N) ans=(ans+1ll*ksm(m-i,n-i*s)*inv[m-i]%mod*ksm(inv[s],i)%mod*inv[n-i*s]%mod*a[i]%mod)%mod; 49 printf("%lld\n",1ll*ans*fac[n]%mod*fac[m]%mod); 50 return 0; 51 }

[BZOJ5306][HAOI2018]染色(容斥+FFT)