标签:blog io os sp for 数据 on 2014 log
思路:
正难则反
//C(M+N,M)*C(Q+M-P,Q)-C(N+M-P,N)*C(M+Q,M);
代码:
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"stack" #include"algorithm" #include"iostream" using namespace std; #define ll long long #define mod 100000007 //C(M+N,M)*C(Q+M-P,Q)-C(N+M-P,N)*C(M+Q,M); ll inverse[100005]; ll power(ll a,ll b) //关于逆元 其实如果mod是素数 则b的逆元其实就是b^(mod-2) { ll ans=1; while(b) { if(b&1) ans=(ans*a)%mod; a=(a*a)%mod; b>>=1; } return ans; } ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0; return a; } ll t,r=exgcd(b,a%b,x,y); t=x; x=y; y=t-a/b*y; return r; } ll get_inverse(ll a) //exgcd求逆元 { ll x,y; exgcd(a,mod,x,y); return (x%mod+mod)%mod; } ll fc(ll n,ll m) { /*ll t1,t2; //数据小的话直接乘起来最后求一次逆元快 t1=t2=1; for(ll i=n;i>m;i--) { t1=(t1*i)%mod; t2=(t2*(i-m))%mod; } return t1*get_inverse(t2)%mod;*/ ll ans=1; //如果数据比较大 先预处理会用到的逆元 然后每次都乘逆元 for(ll i=n; i>m; i--) { ans=(ans*i)%mod; ans=(ans*inverse[i-m])%mod; } return ans; } int main() { ll m,n,p,q; for(int i=1; i<=100000; i++) inverse[i]=power(i,mod-2); //预处理逆元 for(int i=1; i<=100000; i++) inverse[i]=get_inverse(i); //预处理逆元 while(scanf("%lld%lld%lld%lld",&m,&n,&p,&q)!=-1) { ll a,b,c,d,ans; a=fc(m+n,m); b=fc(q+m-p,q); c=fc(n+m-p,n); d=fc(m+q,m); ans=(a*b)%mod-(c*d)%mod; ans=(ans%mod+mod)%mod; printf("%lld\n",ans); } return 0; }
[组合数取模-逆元计算模板] zoj 3624 Count Path Pair
标签:blog io os sp for 数据 on 2014 log
原文地址:http://blog.csdn.net/wdcjdtc/article/details/40921227