BZOJ 2822: [AHOI2012]树屋阶梯
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2822
卡特兰数+高精度。。
#include<cstring> #include<iostream> #include<cstdio> #include<queue> #include<cmath> #include<algorithm> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define low(x) (x&(-x)) #define maxn 505 #define inf int(1e9) #define mm 1000000007 #define ll long long using namespace std; struct data{int len;int x[505]; }A,c,B; int a[1005],ans[1005],pri[1005],b[1005],n,tot; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } void getpri(){ rep(i,2,1000) { if (!b[i]) b[i]=1,pri[++tot]=i; rep(j,1,tot) if (i*pri[j]<=1000) { b[i*pri[j]]=1; if (i%pri[j]==0) break; } } } void get(int x,int y){ int now=1; while (x!=1){ while (x%pri[now]!=0) now++; while (x%pri[now]==0) x/=pri[now],ans[now]+=y; } } data mul(data a,data b){ c.len=a.len+b.len; clr(c.x,0); rep(i,1,a.len) rep(j,1,b.len){ c.x[i+j-1]+=a.x[i]*b.x[j]; c.x[i+j]+=c.x[i+j-1]/10000; c.x[i+j-1]%=10000; } while ((c.x[c.len]==0)&&(c.len!=1)) c.len--; return c; } int main(){ n=read(); getpri(); rep(i,n+2,2*n) get(i,1); rep(i,2,n) get(i,-1); A.x[1]=1; A.len=1; rep(i,1,tot) if (ans[i]){ B.len=1; B.x[1]=pri[i]; while (ans[i]) A=mul(A,B),ans[i]--; } printf("%d",A.x[A.len]); down(i,A.len-1,1) printf("%04d",A.x[i]); puts(""); return 0; }