@ZCDHJ
2019-09-17T07:16:15.000000Z
字数 1621
阅读 712
Lucas定理
推一下柿子
然后把能预处理的预处理出来,其他的递归计算就行了。
#include <iostream>#include <cstdio>typedef long long LL;#define int LLconst int P = 2333;int c[2334][2334], f[2334][2334], pow[2334];inline int read() {register int x = 0;register char ch = getchar();while (!isdigit(ch)) ch = getchar();while (isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}return x;}int C(int n, int k) {if (n < k) return 0;if (n <= P) return c[n][k];return C(n / P, k / P) * c[n % P][k % P] % P;}int F(int n, int k) {if (k < 0) return 0;if (n <= P) return f[n][std::min(n, k)];return ((F(n / P, k / P - 1) * pow[n % P]) % P + (C(n / P, k / P) * f[n % P][k % P]) % P) % P;}signed main() {c[0][0] = 1;for (int i = 1; i <= P; ++i) {c[i][0] = c[i][i] = 1;for (int j = 1; j < i; ++j) {c[i][j] = c[i - 1][j] + c[i - 1][j - 1];if (c[i][j] >= P) c[i][j] -= P;}}pow[0] = 1;for (int i = 1; i <= P; ++i) pow[i] = (pow[i - 1] << 1) % P;for (int i = 0; i <= P; ++i) {f[i][0] = 1;for (int j = 1; j <= P; ++j) {f[i][j] = f[i][j - 1] + c[i][j];if (f[i][j] >= P) f[i][j] -= P;}}int T = read();while (T--) {int n = read(), k = read();printf("%lld\n", F(n, k));}return 0;}
