其中预处理组合数的方法是用的杨辉三角(c[i][j] = c[i-1][j] + c[i-1][j-1]),初始化为(c[0][0] = 1, c[i][0] = c[i][i] = 1 (1leq ileq maxn))。
预处理f的转移方程为(f[i][j] = f[i][j-1] + c[i][j]),初始化为(f[i][0] = 1(0 leq i leq maxn))
放一下代码qwq:
#include <bits/stdc++.h>
using namespace std;
template<typename temp>temp read(temp &x){
x = 0;temp f = 1;char ch;
while(!isdigit(ch = getchar())) (ch == '-') and (f = -1);
for(x = ch^48; isdigit(ch = getchar()); x = (x<<1)+(x<<3)+(ch^48));
return(x *= f);
}
template <typename temp, typename ...Args>void read(temp& a, Args& ...args){read(a), read(args...);}
const int maxn = 2333, p = 2333;
#define ll long long
int t;
ll c[maxn+100][maxn+100], f[maxn+100][maxn+100];
ll lucas(ll n, ll m){
if(!m or n == m) return 1;
if(n < m) return 0;
return c[n%p][m%p]*lucas(n/p,m/p)%p;
}
ll answer(ll n, ll k){
if(k < 0) return 0;
if(!n or !k) return 1;
if(n < p and k < p) return f[n][k];
return (answer(n/p,k/p-1)*f[n%p][p-1]%p+lucas(n/p,k/p)*f[n%p][k%p])%p;
}
signed main(){
read(t);
c[0][0] = 1;
for(int i = 1; i <= 2343; 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])%p;
}
}
for(int i = 0; i <= 2343; i ++) f[i][0] = 1;
for(int i = 0; i <= 2343; i ++){
for(int j = 1; j <= 2343; j ++){
f[i][j] = (f[i][j-1] + c[i][j])%p;
}
}
for(ll n, k; t; t --){
read(n, k);
printf("%lld
", answer(n,k));
}
return 0;
}