1. 程式人生 > >[BZOJ4487][JSOI2015]染色問題(容斥)

[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 }