题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4828
Catalan 数:前几项为 : 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...
原理:
#include <iostream> using namespace std; int extended_gcd(int a,int b, int &x, int &y) { if (b == 0) { x = 1; y = 0; return a; } else { int gcd = extended_gcd(b, a % b, x, y); int t = x; x = y; y = t - (a / b) * y; return gcd; } } int main() { int i, x, y; const int P = 13; for (i = 1; i < P; ++i) { extended_gcd(i, P, x, y); while (x < 0) x += P; printf("1 div %d = %d\n", i, x); } return 0; } //扩展的欧几里德算法求乘法逆元 #include <stdio.h> int ExtendedEuclid(int f, int d, int *result); int main() { int x, y, z; z = 0; printf("输入两个数:\n"); scanf("%d%d", &x, &y); if (ExtendedEuclid(x, y, &z)) printf("%d和%d互素,乘法的逆元是:%d\n", x, y, z); else printf("%d和%d不互素,最大公约数为:%d\n", x, y, z); return 0; } int ExtendedEuclid(int f, int d, int *result) { int x1, x2, x3, y1, y2, y3, t1, t2, t3, q; x1 = y2 = 1; x2 = y1 = 0; x3 = (f >= d) ? f : d; y3 = (f >= d) ? d : f; while (1) { if (y3 == 0) { *result = x3; /* 两个数不互素则result为两个数的最大公约数,此时返回值为零 */ return 0; } if (y3 == 1) { *result = y2; /* 两个数互素则resutl为其乘法逆元,此时返回值为1 */ return 1; } q = x3 / y3; t1 = x1 - q*y1; t2 = x2 - q*y2; t3 = x3 - q*y3; x1 = y1; x2 = y2; x3 = y3; y1 = t1; y2 = t2; y3 = t3; } }
#include <cstdio> #include <cstring> #include <algorithm> #define MAX 1000003 #define MOD 1000000007 #define LL long long using namespace std; LL s[MAX]; LL exgcd(LL a,LL b,LL &x,LL &y){ if(b==0){ x=1; y=0; return a; } LL d = exgcd(b,a%b,x,y); LL t=x; x=y; y=t-a/b*y; return d; } void deal(){ s[1]=s[2]=1; int n = MAX; LL x,y; for(int i=2;i<=n;i++){ s[i+1]=(4*i-6)%MOD; s[i+1]=(s[i+1]*s[i])%MOD; exgcd(i,MOD,x,y); s[i+1]=(s[i+1]*((x+MOD)%MOD))%MOD; } } int main() { int t,n; deal(); scanf("%d",&t); for(int z=1;z<=t;z++){ scanf("%d",&n); printf("Case #%d:\n",z); printf("%I64d\n",s[n+2]); } return 0; }