卡特兰数

2018-11-18  本文已影响0人  徐振杰

https://zhuanlan.zhihu.com/p/31317307
C_{2n}^{n}/(n+1)

火车进出栈问题
和腾讯那道猜拳游戏是一样的

坑的地方:要把最大质数设为12万,因为卡特兰数中有2*n
用到的模板:求素数模板,求n!的模板,高精度模板,高精度可以压位

#include<iostream>
#include<vector>
using namespace std;

const int N = 120010;
bool seen[N];

vector<int> get_prime(int n){
    vector<int> prime;
    for(int i=2;i<n;i++){
        if(!seen[i]){
            prime.push_back(i);
        }
        
        for(int j=i;j<n;j+=i){
            seen[j] = true;
        }
    }
    return prime;
}


int get(int n,int p){
    int cnt = 0;
    while(n){
        cnt += n/p;
        n /= p;
    }
    return cnt;
}

void multi(vector<int>& res,int x){
    
    int c = 0;
    for(int i = 0;i<res.size();i++){
        res[i] = x * res[i] +c;
        c = res[i]/10000;
        res[i] = res[i]%10000;
    }
    while(c){
        res.push_back(c%10000);
        c/=10000;
    }
}

void out(vector<int> res){
    printf("%d",res.back());
    for(int i=res.size()-2;i>=0;i--) printf("%04d",res[i]);
    cout<<endl;
}


int main(){
    int n;
    cin>>n;
    vector<int> prime = get_prime(N);
    vector<int> power(N,0);
    long long ans = 1;
    
    for(int i=0;i<prime.size();i++){
        int p = prime[i];
        power[i] = get(2*n,p)-2*get(n,p);
    }
    
    int k = n+1;
    for(int i=0;prime[i]<=k;i++){
        int cnt = 0;
        int p = prime[i];
        while(k%p==0){
            k = k / p;
            cnt++;
        }
        power[i]-=cnt;
    }
    //while(power.size()&&power.back()==0) power.pop_back();
    
    // for(int i=0;i<power.size();i++){
    //     if(power[i]!=0)
    //         cout<<power[i]<<endl;
    // }
    
    vector<int> res;
    res.push_back(1);
    for(int i=0;i<=N;i++){
        while(power[i]--)
            multi(res,prime[i]);
        
    }

    out(res);
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读