P4345 [SHOI2015]超能粒子炮·改
其中预处理组合数的方法是用的杨辉三角\(c[i][j] = c[i-1][j] + c[i-1][j-1]\),初始化为\(c[0][0] = 1, c[i][0] = c[i][i] = 1\ (1\leq i\leq 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\n", answer(n,k));
}
return 0;
}