慢慢也发现自己的确跟不上节奏了。明明ACM该是个狠好的选择。可是时间至此时此刻,不能说没有机会 只能说甚微了。为了自己的保研大业,在各种oj上乱刷几题,也算是对自己的安慰。
题目:http://ac.jobdu.com/problem.php?pid=1547
题意:给一个空栈和n步操作,保证每一步操作合法并且最终结果保证粘依旧为空。
思路:奇数次操作一定输出0,然后dfs输出偶数次操作前几项
n | 1 | 2 | 3 | 4 | 5 | 6 |
a | 2 | 4 | 6 | 8 | 10 | 12 |
C(n) | 1 | 2 | 5 | 14 | 42 | 132 |
卡特兰数递推公式:h(0)=h(1)=1 , h(n) = [(4*n-2)/n+1]*h(n-1) (n≥2)
同余定理:(a*b)%P=(a%P * b%P)%P (a/b)%P=(a%P * 1/b %P)%P
费马小定理:a^(P-1) % P = 1 (P是质数)
根据费马小定理得:1/a %P = a^(P-2) % P 其中 a^(P-2) %P 利用快速幂取余的办法求得。
快速幂取余(a^b %P):把b拆分成2进制表示从右向左一位一位计算。当第n项为1时令前n项的结果乘以a^(2^(n-1)),并注意实时取余。
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
#define MOD 1000000007
typedef long long LL;
LL h[505];
LL exp_mod(LL a){
LL b = MOD - 2;
LL res = 1;
while (b){
if (b & 1)
res = (res*a) % MOD;
b >>= 1;
a = (a*a) % MOD;
}
return res;
}
void init(){
LL i;
h[0] = h[1] = 1;
for (i = 2; i <= 500; i++)
h[i] = (((4 * i - 2) % MOD * exp_mod(i + 1)) % MOD * h[i - 1]) % MOD;
}
int main(){
freopen("in.txt", "r", stdin);
int n;
init();
while (scanf("%d", &n) != EOF){
if (n % 2 == 0)
printf("%lld\n", h[n / 2]);
else printf("0\n");
}
return 0;
}