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 }  
View Code

1272: [BeiJingWc2008]Gate Of Babylon

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 195  Solved: 90
[Submit][Status]

Description

Input

Output

Sample Input

Sample Output

12

HINT

posted @ 2015-01-20 13:03  ZYF-ZYF  Views(370)  Comments(0Edit  收藏  举报