[BZOJ4487][JSOI2015]染色问题(容斥)

一开始写了7个DP方程,然后意识到这种DP应该都会有一个通式。

三个条件:有色行数为n,有色列数为m,颜色数p,三维容斥原理仍然成立。

于是就是求:$\sum_{i=0}^{n}\sum_{j=0}^{m}\sum_{k=0}^{p}(-1)^{n+m+p-i-j-k}\times C_n^i\times C_m^j\times C_p^k\times (k+1)^{ij}$

复杂度$O(n^3)$

可以根据二项式定理优化:

https://blog.csdn.net/werkeytom_ftd/article/details/52527740

复杂度$O(n^2\log)$

 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=410,mod=1e9+7;
 7 int n,m,p,ans,fac[N],inv[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 int C(int n,int m){ return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod; }
17 
18 int main(){
19     freopen("bzoj4487.in","r",stdin);
20     freopen("bzoj4487.out","w",stdout);
21     scanf("%d%d%d",&n,&m,&p);
22     fac[0]=1; rep(i,1,400) fac[i]=1ll*fac[i-1]*i%mod;
23     inv[400]=ksm(fac[400],mod-2);
24     for (int i=399; ~i; i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
25     rep(i,0,n) rep(k,0,p){
26         int t=1ll*C(n,i)*C(p,k)%mod*ksm((1-ksm(k+1,i)+mod)%mod,m)%mod;
27         if ((n+m+p-i-k)&1) ans=(ans-t+mod)%mod; else ans=(ans+t)%mod;
28     }
29     printf("%d\n",ans);
30     return 0;
31 }

 

posted @ 2018-12-02 19:53  HocRiser  阅读(253)  评论(0编辑  收藏  举报