[洛谷P4345][SHOI2015]超能粒子炮·改

题目大意:给你$n,k$,求:
$$
sumlimits_{i=0}^kinom n ipmod{2333}
$$
题解:令$p=2333,f(n,k)equivsumlimits_{i=0}^kinom n ipmod p$
$$
egin{align*}
f(n,k)equiv&sumlimits_{i=0}^kinom n ipmod p\    equiv&sumlimits_{i=0}^kinom{iglfloorfrac npig floor}{iglfloorfrac ipig floor}inom{nmod p}{imod p}pmod p\
end{align*}\
令s=leftlfloordfrac k p ight floor
$$

$$
egin{align*}
f(n,k)equiv&[sumlimits_{i=0}^{p-1}inom{nmod p}{i}][sumlimits_{i=0}^{s-1}inom{iglfloorfrac n pig floor}{i}]\
    &+inom{leftlfloorfrac np ight floor}{s}sumlimits_{i=sp}^kinom{nmod p}{imod p}pmod p\
    equiv&[sumlimits_{i=0}^{p-1}inom{nmod p}{i}][sumlimits_{i=0}^{s-1}inom{iglfloorfrac n pig floor}{i}]\
    &+inom{leftlfloorfrac np ight floor}{s}sumlimits_{i=0}^{kmod p}inom{nmod p}{i}pmod p\
    equiv&f(nmod p, p-1)f(leftlfloordfrac np ight floor,s-1)\
    &+inom{iglfloorfrac npig floor}{s}f(nmod p,kmod p)pmod p\
end{align*}
$$

卡点:未注意$n,kleqslant10^{18}$



C++ Code:

#include <cstdio>
const int mod = 2333;
#define maxn mod
inline void reduce(int &x) { x += x >> 31 & mod; }

int Tim;
long long n, k;
int com[maxn][maxn], pre[maxn][maxn];

int C(long long a, long long b) {
	if (a < b) return 0;
	if (a < mod) return com[a][b];
	return com[a % mod][b % mod] * C(a / mod, b / mod) % mod;
}
int solve(long long n, long long k) {
	if (k < 0) return 0;
	if (n < mod && k < mod) return pre[n][k];
	const long long s = k / mod;
	return (pre[n % mod][mod - 1] * solve(n / mod, s - 1) + pre[n % mod][k % mod] * C(n / mod, s)) % mod;
}
int main() {
	scanf("%d", &Tim);
	for (int i = 0; i < mod; ++i) {
		*com[i] = *pre[i] = 1;
		for (int j = 1; j <= i; ++j) {
			reduce(com[i][j] = com[i - 1][j] + com[i - 1][j - 1] - mod);
			reduce(pre[i][j] = pre[i][j - 1] + com[i][j] - mod);
		}
		for (int j = i + 1; j < mod; ++j) reduce(pre[i][j] = pre[i][j - 1] + com[i][j] - mod);
	}
	while (Tim --> 0) {
		scanf("%lld%lld", &n, &k);
		printf("%d
", solve(n, k));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Memory-of-winter/p/10283798.html