bzoj 5306: [Haoi2018]染色
2018-04-30 17:20
211 查看
Description
Solution
写了个傻逼的 \(O(n+m*log^2)\) 的做法,卡了一下午才过 \(bzoj\)首先设 \(f[i]\) 表示至少有 \(i\) 种颜色数量为 \(s\)
显然 \(f[i]=C_{m}^{i}*C_{n}^{i*s}*\frac{(i*s)!}{s!^i}*m^{n-i*s}\)
设 \(g[i]\) 表示至少有 \(i\) 种颜色数量为 \(s\)
然后写出了个傻逼式子:
\(g
=f
\)
\(g[i]=f[i]-\sum_{j=i+1}^{n}g[j]*C_j^i\)
然后分治\(NTT\),强行多一个 \(log\),实际上对 \(f\) 数组直接容斥就行了
#include<bits/stdc++.h> #define RG register using namespace std; template<class T>void gi(T &x){ int f;char c; for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1; for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f; } const int N=1e7+10,M=1e5+10,mod=1004535809; int n,m,s,w[M],f[M],Fac ,inv ,g[M],lim,D,INV ; inline int qm(int x,int k){ int sum=1; while(k){ if(k&1)sum=1ll*sum*x%mod; x=1ll*x*x%mod;k>>=1; } return sum; } inline int C(int a,int b){ return 1ll*Fac[a]*inv[b]%mod*inv[a-b]%mod; } int E,L=0,R[M*4],G[M*4]; inline void NTT(int *A){ for(RG int i=0;i<E;i++)if(i<R[i])swap(A[i],A[R[i]]); for(RG int i=1;i<E;i<<=1){ int t0=G[i],x,y; for(RG int j=0;j<E;j+=i<<1){ int t=1; for(RG int k=0;k<i;k++,t=1ll*t*t0%mod){ x=A[j+k];y=1ll*A[j+k+i]*t%mod; A[j+k]=(x+y)%mod;A[j+k+i]=(x-y+mod)%mod; } } } } inline void mul(int *A,int *B){ NTT(A);NTT(B); for(RG int i=0;i<=E;i++)A[i]=1ll*A[i]*B[i]%mod; NTT(A); reverse(A+1,A+E); for(RG int i=0,t=INV[E];i<=E;i++)A[i]=1ll*A[i]*t%mod; } int A[M*4],B[M*4]; inline void solve(int l,int r){ if(l==r){ f[lim-l]=(f[lim-l]-1ll*g[l]*inv[lim-l]%mod+mod)%mod; return ; } int mid=(l+r)>>1,len=(r-l+1); solve(l,mid); L=0; for(E=1;E<=len;E<<=1)L++; for(RG int i=0;i<E;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1)),A[i]=0,B[i]=inv[i]; for(RG int i=l;i<=mid;i++)A[i-l]=1ll*f[lim-i]*Fac[lim-i]%mod; mul(A,B); for(RG int i=mid+1;i<=r;i++)g[i]=(g[i]+A[i-l])%mod; solve(mid+1,r); } int main(){ freopen("pp.in","r",stdin); freopen("pp.out","w",stdout); cin>>n>>m>>s;INV[0]=INV[1]=1;G[1]=qm(3,(mod-1)/2); for(RG int i=2;i<400000;i++){ G[i]=qm(3,(mod-1)/(i<<1)); INV[i]=(mod-1ll*(mod/i)*INV[mod%i]%mod)%mod; } for(RG int i=0;i<=m;i++)gi(w[i]); lim=min(n/s,m),D=max(n,m); Fac[0]=inv[0]=inv[1]=INV[0]=INV[1]=1; for(RG int i=1;i<=D;i++)Fac[i]=1ll*Fac[i-1]*i%mod; inv[D]=qm(Fac[D],mod-2); for(RG int i=D-1;i>=2;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod; for(RG int i=0;i<=lim;i++) f[i]=1ll*C(m,i)*C(n,i*s)%mod*Fac[i*s]%mod*qm(qm(Fac[s],i),mod-2)%mod*qm(m-i,n-i*s)%mod; solve(0,lim); int ans=0; for(RG int i=0;i<=lim;i++)ans=(ans+1ll*f[i]*w[i])%mod; cout<<ans<<endl; return 0; }
相关文章推荐
- BZOJ5306 HAOI2018染色(容斥原理+NTT)
- [HAOI2018][bzoj5306] 染色 [容斥原理+NTT]
- BZOJ5306 [HAOI2018]染色 【组合数 + 容斥 + NTT】
- bzoj 4033: [HAOI2015]树上染色 [树形DP]
- bzoj 5303: [Haoi2018]反色游戏
- BZOJ 4033 [HAOI2015]树上染色 ——树形DP
- BZOJ4033 [HAOI2015]树上染色
- BZOJ4033:[HAOI2015]树上染色(树形dp)
- 【BZOJ】4033: [HAOI2015]树上染色 树上背包
- BZOJ4033 [HAOI]树上染色
- [bzoj4033][HAOI2015]树上染色_树形dp
- bzoj 4033: [HAOI2015]树上染色 树形dp
- BZOJ4033[HAOI2015] 树上染色 解题报告【树上DP】
- bzoj4033[HAOI2015] 树上染色
- 【HAOI2015】【BZOJ4033】T1树上染色
- BZOJ4033 [HAOI2015]树上染色 【树形dp】
- [树形DP]BZOJ 4033—— [HAOI2015]树上染色
- bzoj 4033: [HAOI2015]树上染色
- 【BZOJ4033】【HAOI2015】树上染色
- 【BZOJ4033】【HAOI2015】树上染色 树形DP