1119 机器人走方格 V2(卢卡斯大组合数取膜)

思路:f(i,j)表示机器人从左上角到(i,j)的方法数,则f(i,j)=f(i-1,j)+f(i,j-1),这是因为机器人只能走下或走右。模拟一遍可得f(i,j)=C(i+j-2,m-1),由于i,j比较大,所以利用卢卡斯大组合数取膜。

 1 #include <iostream>
 2 #include <queue>
 3 #include <stack>
 4 #include <cstdio>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <bitset>
 9 #include <algorithm>
10 #include <cmath>
11 #include <cstring>
12 #include <cstdlib>
13 #include <string>
14 #include <sstream>
15 #include <time.h>
16 #define x first
17 #define y second
18 #define pb push_back
19 #define mp make_pair
20 #define lson l,m,rt*2
21 #define rson m+1,r,rt*2+1
22 #define mt(A,B) memset(A,B,sizeof(A))
23 #define mod 1000000007
24 using namespace std;
25 typedef long long LL;
26 const double PI = acos(-1);
27 const int N=1e5+10;
28 const int inf = 0x3f3f3f3f;
29 const LL INF=0x3f3f3f3f3f3f3f3fLL;
30 LL exp_mod(LL a, LL b, LL p)
31 {
32     LL res = 1;
33     while(b != 0)
34     {
35         if(b&1) res = (res * a) % p;
36         a = (a*a) % p;
37         b >>= 1;
38     }
39     return res;
40 }
41 LL Comb(LL a, LL b, LL p)
42 {
43     if(a < b)   return 0;
44     if(a == b)  return 1;
45     if(b > a - b)   b = a - b;
46     LL ans = 1, ca = 1, cb = 1;
47     for(LL i = 0; i < b; ++i)
48     {
49         ca = (ca * (a - i))%p;
50         cb = (cb * (b - i))%p;
51     }
52     ans = (ca*exp_mod(cb, p - 2, p)) % p;
53     return ans;
54 }
55 LL Lucas(int n, int m, int p)
56 {
57     LL ans = 1;
58     while(n&&m&&ans)
59     {
60         ans = (ans*Comb(n%p, m%p, p)) % p;
61         n /= p;
62         m /= p;
63     }
64     return ans;
65 }
66 int main()
67 {
68 #ifdef Local
69     freopen("data.txt","r",stdin);
70 #endif
71      int m,n;
72      cin>>n>>m;
73      cout<<Lucas(n+m-2,m-1,mod)<<endl;
74 #ifdef Local
75     cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
76 #endif
77 }
View Code

 

posted @ 2017-01-18 16:42  Kcl886  阅读(200)  评论(0编辑  收藏  举报