Zoj--3624(乘法逆元,组合数)
2014-11-13 23:04:17
思路:这题的思路要倒过来,求不想交的路径对,那么先求相交的路径对,再用总数减一下。
相交路径对:A->C × B->D 方案数,因为先从A到C,B到D,找到两路径交点,再把A->交点->C的路径改为A->交点->D,B同理,这样就能使得两路径有交点了。
1 /************************************************************************* 2 > File Name: 3624.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Thu 13 Nov 2014 10:35:38 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const ll mod = 100000007; 27 28 ll Ex_gcd(ll a,ll b,ll &x,ll &y){ 29 if(b == 0){ 30 x = 1; 31 y = 0; 32 return a; 33 } 34 ll g = Ex_gcd(b,a % b,x,y); 35 ll t = x; 36 x = y; 37 y = t - a / b * y; 38 return g; 39 } 40 41 ll Inverse(ll v){ 42 ll x,y; 43 Ex_gcd(v,mod,x,y); 44 return (x % mod + mod) % mod; 45 } 46 47 ll Cal(ll a,ll b){ 48 ll up = 1,down = 1; 49 for(ll i = a; i > b; --i){ 50 up = (up * i) % mod; 51 down = (down * (i - b)) % mod; 52 } 53 return up * Inverse(down) % mod; 54 } 55 56 int main(){ 57 ll m,n,p,q; 58 while(cin >> m >> n >> p >> q){ 59 cout << ((Cal(m + q - p,q) * Cal(m + n,m) - 60 Cal(m + q,m) * Cal(m + n - p,n)) % mod + mod) % mod << endl; 61 } 62 return 0; 63 }