题面
https://www.luogu.org/problem/P3200
题解
从小到大给“奇”和“偶”的序列加数。奇的序列的长度不能超过偶的序列的长度,把加入偶序列记做写一个$($,加入奇序列记做写一个$)$,就是一个括号序列问题,所以答案是一个卡特兰数。
要求输出第$n$个卡特兰数的值膜$p$($p$不一定是质数),我们用$H(i)=H(i-1) imes frac{4n-2}{n+1}$来算,把每个数唯一分解(乘除转加减)就行了。(记得这个$trick$还是上梵高课的时候第一次$get$到的)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ri register int #define N 1000500 using namespace std; int n,p; int c[N],f[4*N],prime[N]; int ton[4*N]; void add(int x) { while (1) { if (!f[x]) break; ton[f[x]]++; x/=f[x]; } if (x!=1) ton[x]++; } void del(int x) { while (1) { if (!f[x]) break; ton[f[x]]--; x/=f[x]; } if (x!=1) ton[x]--; } int main() { cin>>n>>p; c[1]=1; int cnt=0; for (ri i=2;i<=4*N;i++) { if (!f[i]) prime[++cnt]=i; for (ri j=1;i*prime[j]<=4*N;j++) { f[i*prime[j]]=prime[j]; if (i%prime[j]==0) break; } } for (ri i=2;i<=n;i++) { add(4*i-2); del(i+1); } long long ans=1; for (ri i=1;i<=4*N;i++) while (ton[i]) ton[i]--,ans*=i,ans%=p; cout<<ans<<endl; return 0; }