BZOJ 1485: [HNOI2009]有趣的数列
对任意前缀,前 \(n\) 个数被选的不小于没被选的,否则,即使奇数项贴着下界继续放,偶数项也会不满足第 \(2\) 或 第 \(3\) 个条件。
所以就变成了卡特兰数的定义
\(C_n = \binom{2n}{n} - \binom{2n}{n+1}=\dfrac{2n!}{n!(n+1)!}\)
组合数对合数取模,枚举每一个质因子的贡献即可
#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define pii pair<int, int>
#define lp p << 1
#define rp p << 1 | 1
#define mid ((l + r) >> 1)
#define ll long long
#define db double
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
#define Edg int cnt=1,head[N],to[N*2],ne[N*2];void addd(int u,int v){to[++cnt]=v;ne[cnt]=head[u];head[u]=cnt;}void add(int u,int v){addd(u,v);addd(v,u);}
#define Edgc int cnt=1,head[N],to[N*2],ne[N*2],c[N*2];void addd(int u,int v,int w){to[++cnt]=v;ne[cnt]=head[u];c[cnt]=w;head[u]=cnt;}void add(int u,int v,int w){addd(u,v,w);addd(v,u,w);}
#define es(u,i,v) for(int i=head[u],v=to[i];i;i=ne[i],v=to[i])
const int N = 2e6 + 7;
int MOD, prime[N], prin;
int qp(int a, int b) {
int ans = 1;
for (; b; a = 1LL * a * a % MOD, b >>= 1)
if (b & 1) ans = 1LL * a * ans % MOD;
return ans % MOD;
}
int solve(int n, int p) {
int base = p;
int ans = 0;
while (base <= n) {
ans += n / base;
if (1LL * base * p > n) break;
base *= p;
}
return ans;
}
int main() {
int n;
scanf("%d%d", &n, &MOD);
static bool vis[N];
rep (i, 2, 2 * n + 2) {
if (!vis[i]) prime[++prin] = i;
rep (j, 1, prin + 1) {
if (1LL * i * prime[j] > 2 * n + 1) break;
vis[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
int ans = 1;
rep (i, 1, prin + 1) {
int cnt = solve(2 * n, prime[i]) - solve(n, prime[i]) - solve(n + 1, prime[i]);
ans = 1LL * ans * qp(prime[i], cnt) % MOD;
}
printf("%d\n", ans);
}

浙公网安备 33010602011771号