← 全部文章

CF582D Number of Binominal Coefficients 题解

本文目录(3 节)
  1. 题意
  2. 题解
  3. 代码

CF582D Number of Binominal Coefficients

题意

  • 给定质数 pp 和整数 α,A\alpha,A,求满足 0≤k≤n≤A0 \le k \le n \le A 且 pα∣(nk)p^{\alpha}|\binom nk 的数对 (n,k)(n,k) 的个数。
  • p,α≤109p,\alpha \le 10^9,A<101000A < 10^{1000},答案对 109+710^9+7 取模。

题解

库默尔定理:质数 pp 进制下 a+ba+b 的进位次数等于 (a+ba)\binom{a+b}a 的标准分解式中 pp 的次数。

因此题意变成求 0≤a+b≤s0 \le a + b \le s 且 a+ba + b 在 pp 进制下的进位次数至少为为 cc 的非负整数对 (a,b)(a, b) 的个数。

数位 dp 即可,时间复杂度 O(log⁡ps(log⁡s+log⁡ps))\mathcal O(\log_{p} s (\log s + \log_{p} s))。

代码

const int N = 4e3 + 7;
int p, c, n, a[N];
char s[N];
ll b[N];
modint f[2][2][N], g[2][2][N], ans;

int main() {
	rd(p), rd(c), rds(s, n);
	for (int i = 1; i <= n; i++) a[i] = s[n+1-i] - '0';
	for (int i = n; i; i--) {
		for (int j = 1; j < N - 1; j++) b[j] *= 10;
		b[1] += a[i];
		for (int j = 1; j < N - 1; j++)
			if (b[j] >= p) b[j+1] += b[j] / p, b[j] %= p;
	}
	for (int i = 1; i <= N; ++i) a[i] = b[i];
	n = N - 1;
	while (n && !a[n]) --n;
	if (!n) return print(0), 0;
	f[1][0][0] = 1;
	for (int i = n; i; i--) {
		modint a0 = 1ll * p * (p + 1) / 2 % P;
		modint a1 = 1ll * p * (p - 1) / 2 % P;
		modint a2 = 1ll * a[i] * (a[i] + 1) / 2 % P;
		modint a3 = 1ll * a[i] * (a[i] - 1) / 2 % P;
		modint a4 = 1ll * a[i] * (p + p - a[i] - 1) / 2 % P;
		modint a5 = 1ll * a[i] * (p + p - a[i] + 1) / 2 % P;
		for (int j = 0; j <= n + 1 - i; j++) g[0][0][j] = g[0][1][j] = g[1][0][j] = g[1][1][j] = 0;
		for (int j = 0; j <= n - i; j++) {
			modint f0 = f[0][0][j], f1 = f[0][1][j], f2 = f[1][0][j], f3 = f[1][1][j];
			g[0][0][j] += f0 * a0 + f2 * a2;
			g[0][1][j] += f0 * a1 + f2 * a3;
			g[1][0][j] += f2 * (a[i] + 1);
			g[1][1][j] += f2 * a[i];
			g[0][0][j+1] += f1 * a1 + f3 * a4;
			g[0][1][j+1] += f1 * a0 + f3 * a5;
			g[1][0][j+1] += f3 * (p - a[i] - 1);
			g[1][1][j+1] += f3 * (p - a[i]);
		}
		swap(f, g);
	}
	for (int i = c; i <= n; i++) ans += f[0][0][i] + f[1][0][i];
	print(ans);
	return 0;
}

标签:DP、数位 DP、组合计数

评论

    填写昵称即可留言。评论经站主审核后公开,请勿提交私人信息。

    正在连接评论服务…