[xdoj1158]阶乘求逆元(常用于求组合数)

http://acm.xidian.edu.cn/problem.php?id=1158

 解题关键:此题注意将$\sum\limits_{i = 0}^x {C_x^iC_y^{i + k}}$转化为$C_{x + y}^{x + k}$

 

利用二项式定理,

一方面,

${(1 + a)^y}{(1 + \frac{1}{a})^x}$的${a^k}$项的系数,第一个二项式的${a^j}$的系数$C_y^j$,第二个二项式的${a^{ - i}}$系数为$C_x^i$,令$j - i = k$,$j = i + k$,即$\sum\limits_{i = 0}^x {C_x^iC_y^{i + k}}$

另一方面,

${(1 + a)^y}{(1 + \frac{1}{a})^x} = {(1 + a)^{x + y}}{a^{ - x}}$,此时${a^k}$项的系数为$C_{x + y}^{x + k}$,得证。

 

1、打表

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long  ll;
 4 const ll mod=1e9+7;
 5 ll x,y,k;
 6 ll fac[2000005],inv[2000005];
 7 
 8 ll mod_pow(ll x,ll n,ll mod){
 9     ll res=1;
10     while(n){
11         if(n&1) res=res*x%mod;
12         n>>=1;
13         x=x*x%mod;
14     }
15     return res;
16 }
17 
18 ll Inv(ll x){
19     return mod_pow(x,mod-2,mod);
20 }
21 
22 int main(){
23     fac[1]=1;
24     for(int i=2;i<=2000000;i++) fac[i]=fac[i-1]*i%mod;//预处理一下,阶乘 
25     inv[2000000]=mod_pow(fac[2000000],mod-2,mod);//Fac[N]^{MOD-2}
26     for(int i=2000000-1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;
27     
28     
29     while(~scanf("%lld%lld%lld",&x,&y,&k)){
30         if(y==k)  printf("1\n");
31         else if(y<k)  printf("0\n");
32       //  else   printf("%lld\n",fac[x+y]*inv(fac[x+k])%mod*inv(fac[y-k])%mod);
33       else printf("%lld\n",(fac[x+y]%mod*inv[x+k]%mod*inv[y-k]%mod+mod)%mod);
34     }
35     return 0;
36 }

 

 

2、打表+逆元实现

为什么是$n{!^{\bmod  - 2}}$

 

$n{!^{p - 2}}*n! = n{!^{p - 1}} = 1\bmod {\rm{ p;}}$(费马小定理)p为质数,此题中即为mod

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long  ll;
 4 const ll mod=1e9+7;
 5 ll x,y,k;
 6 ll fac[2000005],inv[2000005];
 7 
 8 ll mod_pow(ll x,ll n,ll mod){
 9     ll res=1;
10     while(n){
11         if(n&1) res=res*x%mod;
12         n>>=1;
13         x=x*x%mod;
14     }
15     return res;
16 }
17 
18 ll Inv(ll x){
19     return mod_pow(x,mod-2,mod);
20 }
21 
22 int main(){
23     fac[1]=1;
24     for(int i=2;i<=2000000;i++) fac[i]=fac[i-1]*i%mod;//预处理一下,阶乘 
25     //inv[2000000]=mod_pow(fac[2000000],mod-2,mod);//Fac[N]^{MOD-2}
26     //for(int i=2000000-1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;
27     
28     
29     while(~scanf("%lld%lld%lld",&x,&y,&k)){
30         if(y==k)  printf("1\n");
31         else if(y<k)  printf("0\n");
32         else   printf("%lld\n",fac[x+y]*Inv(fac[x+k])%mod*Inv(fac[y-k])%mod);
33       //else printf("%lld\n",(fac[x+y]%mod*inv[x+k]%mod*inv[y-k]%mod+mod)%mod);
34     }
35     return 0;
36 }

 

posted @ 2017-05-04 19:53  Elpsywk  阅读(1368)  评论(0编辑  收藏  举报