首页 > 代码库 > HNU 12933 Random Walks Catalan数 阶乘求逆元新技能

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

  一个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数。

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

 

代码: 

 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 Phantom0141         freopen("HNU12933.txt", "r", stdin);42     #endif //Phantom0143 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

 

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

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数 阶乘求逆元新技能