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 }

 

posted @ 2014-11-13 23:07  Naturain  阅读(154)  评论(0编辑  收藏  举报