BZOJ1272: [BeiJingWc2008]Gate Of Babylon
题解:
多重集合的组合数?还是0-m?有些元素有个数限制?
多重集合的组合数可以插板法,0-m直接利用组合数的公式一遍求出来,个数限制注意到只有15个,那我们就暴力容斥了
AC了真舒畅。。
注意开long long
1 ll n,m,a[20],k,p,ans,fac[maxn],inv[maxn]; 2 inline ll c(ll n,ll m) 3 { 4 if(n<m)return 0; 5 if(n<p&&m<p)return fac[n]*inv[m]%p*inv[n-m]%p; 6 return c(n%p,m%p)*c(n/p,m/p)%p; 7 } 8 inline void dfs(int x,int w1,ll w2) 9 { 10 if(x==k+1){ans=(ans+w1*(c(m+n-w2,n)-c(n-w2-1,n)))%p;return;}//cout<<n<<' '<<m<<' '<<w2<<' '<<n+m-w2<<' '<<n<<' '<<ans<<endl;return;} 11 dfs(x+1,-w1,w2+a[x]+1); 12 dfs(x+1,w1,w2); 13 } 14 15 int main() 16 17 { 18 19 freopen("input.txt","r",stdin); 20 21 freopen("output.txt","w",stdout); 22 23 n=read();k=read();m=read();p=read(); 24 fac[0]=1; 25 for1(i,p-1)fac[i]=fac[i-1]*i%p; 26 inv[0]=inv[1]=1; 27 for2(i,2,p-1)inv[i]=inv[i-p%i]*(p/i+1)%p; 28 for1(i,p-1)inv[i]=inv[i]*inv[i-1]%p; 29 for1(i,k)a[i]=read(); 30 dfs(1,1,0); 31 cout<<(ans+p)%p<<endl; 32 33 return 0; 34 35 }
1272: [BeiJingWc2008]Gate Of Babylon
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 195 Solved: 90
[Submit][Status]
Description
Input
Output
Sample Input
Sample Output
12