AcWing 1316. 有趣的数列 (卡特兰数推导)

1316. 有趣的数列
卡特兰数求很轻松,关键是如何理解这道题目就是卡特兰数。
通过找数字规律的,就算了吧

#include<stdio.h>
using namespace std;

// C(2n,n)-C(2n,n+1)
typedef long long ll;

const int N =  2e6+10;
int primes[N], cnt = 0;
bool vis[N];
int n, P;
int s1[N], s2[N];

void getPrimes(){
    
    
    for(int i=2;i<N;i++){
    
    
        if(!vis[i]) primes[cnt++] = i;
        for(int j=0;i*primes[j]<N;j++){
    
    
            vis[i*primes[j]] = 1;
            if(i%primes[j]==0) break;
        }
    }
}

int f(int n,int p){
    
    
    int res = 0;
    while(n){
    
    
        res += n/p;
        n /= p;
    }
    return res;
}

void getS(){
    
    
    for(int i=0;i<cnt;i++){
    
    
        int p = primes[i];
        s1[i] = f(2*n,p)-f(n,p)-f(n,p);
        s2[i] = f(2*n,p)-f(n+1,p)-f(n-1,p);
    }
}


int C(int s[]){
    
    
    ll ans = 1;
    for(int i=0;i<cnt;i++){
    
    
        for(int j=0;j<s[i];j++){
    
    
            ans = (ans*primes[i])%P;
        }
    }
    return ans%P;
}

int main(){
    
    
    scanf("%d%d",&n,&P);
    getPrimes();
    getS();
    ll ans = ((C(s1)-C(s2))%P+P)%P;
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44846324/article/details/108785812