2016-5-22 百度之星第三題--瞬間移動

http://acm.hdu.edu.cn/showproblem.php?pid=5698php

剛開始計算了下,就是當前位置等於其左邊的值加上上邊的值,因而寫了個二維數組,dp[2][100005],進行存儲,而後複雜度爲o(n*m),超時了ios

因而,楊神牛,提醒了我說楊輝三角,而後,寫了個組合數取模,但當組合數比較大時,計算的組合數取模不對數組

百度了下大組合數取模,而後,知道轉化爲階乘來算,用上LUCAS定理,乘法逆元,快速冪ide

LUCAS定理: Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p) spa

乘法逆元:code

 (a/b)%mod ,其實若是mod是質數的時候能夠用費馬小定理來作,即blog

a*b^(mod-2)//這個比較經常使用ci

 1 #include <cmath>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <memory>
 7 #include <string>
 8 #include <queue>
 9 #include <map>
10 #include <stdio.h>
11 #include <vector>
12 #include <stack>
13 #include <fstream>
14 #include <set>
15 #define N 200005
16 #define mod 1000000007
17 using namespace std;
18 long long mod_pow(int a,int n,int p)
19 {
20     long long ret=1;
21     long long A=a;
22     while(n)
23     {
24         if (n & 1)
25             ret=(ret*A)%p;
26         A=(A*A)%p;
27         n>>=1;
28     }
29     return ret;
30 }
31 
32 long long factorial[N];
33 
34 void init()
35 {
36     factorial[0] = 1;
37     for(int i = 1;i <= N;i++)
38         factorial[i] = factorial[i-1]*i%mod;
39 }
40 
41 long long Lucas(long long a,long long k,long long p) //求C(n,m)%p p最大爲10^5。a,b能夠很大!
42 {
43     long long re = 1;
44     while(a && k)
45     {
46         long long aa = a%p;long long bb = k%p;
47         if(aa < bb) return 0;
48         re = re*factorial[aa]*mod_pow(factorial[bb]*factorial[aa-bb]%p,p-2,p)%p;
49         a /= p;
50         k /= p;
51     }
52     return re;
53 }
54 int main()
55 {
56     //freopen("in.txt","r",stdin);
57     init();
58     int n,m;
59     while(cin>>n>>m)
60     {
61         if(n==2&&m==2)
62         {
63             cout<<1<<endl;
64         }
65         else
66         {
67             cout<<Lucas(n+m-4,m-2,mod)<<endl;
68         }
69     }
70     return 0;
71 }
View Code
相關文章
相關標籤/搜索