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;
} 
原文地址:https://www.cnblogs.com/ctlchild/p/5131429.html