码迷,mamicode.com
首页 > 其他好文 > 详细

HNU 12933 Random Walks Catalan数 阶乘求逆元新技能

时间:2014-08-27 18:09:18      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   ar   art   

  一个Catalan数的题,打表对每个数都求一次逆元会T,于是问到了一种求阶乘逆元的打表新方法。 比如打一个1~n的阶乘的逆元的表,假如叫inv[n],可以先用费马小定理什么的求出inv[n],再用递推公式求出前面的项。

  我们记数字 x 的逆元为f(x) (%MOD)。

  因为 n! = (n-1)! * n

  所以 f(n!) = f( (n-1)! * n) = f( (n-1)! ) * f(n)。

  所以 f( (n-1)! ) = f(n!) * f( f(n) ) = f(n!) * n   (逆元的逆元就是他自身)

这样子我们就可以用后项推出前面的项了。

 

题目是说,有一个人从0点开始走路,每次可以向前走或者向后走,每次可以走一步,但是所有的位置必须大于等于0,问走过2n步之后又回到0点有多少种方法。

  其实,如果我们把向前走看做是进栈,向后走看做是出栈,方法数就是Catalan数。

  所以我们只需要打一张表然后查表就好了。

 

代码: 

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <string>
 8 #include <queue>
 9 #include <stack>
10 #include <vector>
11 #include <map>
12 #include <set>
13 #include <functional>
14 #include <cctype>
15 #include <time.h>
16 
17 using namespace std;
18 
19 typedef __int64 ll;
20 
21 const int INF = 1<<30;
22 const int MAXN = (int) 2e6+55;
23 const ll MOD = (ll) 1e9+7;
24 
25 ll ans[MAXN];
26 ll fac[MAXN];
27 ll inv[MAXN];
28 
29 inline ll myPow(ll x, ll n) {
30     ll res = 1;
31     while (n>0) {
32         if (n&1) res = (res*x)%MOD;
33         x = (x*x)%MOD;
34         n >>= 1;
35     }
36     return res;
37 }
38 
39 int main() {
40     #ifdef Phantom01
41         freopen("HNU12933.txt", "r", stdin);
42     #endif //Phantom01
43 
44     fac[0] = 1;
45     for (int i = 1; i < MAXN; i++) fac[i] = (fac[i-1]*i)%MOD;
46     inv[MAXN-1] = myPow(fac[MAXN-1], MOD-2);
47     for (int i = MAXN-2; i > 0; i--) {
48         inv[i] = (inv[i+1]*(i+1))%MOD;
49     }
50 
51     for (int i = 1; i < (MAXN>>1); i++)
52         ans[i] = (((fac[2*i]*inv[i+1])%MOD)*inv[i])%MOD;
53 
54     int T;
55     scanf("%d", &T);
56 
57     int n;
58     while (T--) {
59         scanf("%d", &n);
60         printf("%I64d\n", ans[n]);
61     }
62 
63     return 0;
64 }
View Code

 

其中,这个是用来打阶乘逆元的:

bubuko.com,布布扣
1     //阶乘
2     fac[0] = 1;
3     for (int i = 1; i < MAXN; i++) fac[i] = (fac[i-1]*i)%MOD;
4     //逆元
5     inv[MAXN-1] = myPow(fac[MAXN-1], MOD-2);
6     for (int i = MAXN-2; i > 0; i--) {
7         inv[i] = (inv[i+1]*(i+1))%MOD;
8     }
View Code

 

HNU 12933 Random Walks Catalan数 阶乘求逆元新技能

标签:style   blog   http   color   os   io   for   ar   art   

原文地址:http://www.cnblogs.com/Phantom01/p/3939759.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!