以下除法一律为整除。
求(sum_{i=0}^kC_n^i mod p,p=2333)
设(f(i,j)=sum_{k=0}^jC_i^k)
(f(n,k)=sum_{i=0}^kC_n^i)
当(kle p,nle p),预处理(0le ile p,0le jle i)的(C_i^j)及其前缀和。
否则
(f(n,k))
(=sum_{i=0}^kC_{n mod p}^{i mod p} imes C_{n/p}^{i/p})
(=sum_{b=0}^{k/p-1}sum_{i=0}^{p-1}(C_{n mod p}^i imes C_{n/p}^{b})+C_{n/p}^{k/p} imes(sum_{i=0}^{k mod p}C_{n mod p}^i))
(=sum_{b=0}^{k/p-1}C_{n/p}^{b} imessum_{i=0}^{p-1}C_{n mod p}^i+C_{n/p}^{k/p} imes(sum_{i=0}^{k mod p}C_{n mod p}^i))
(=f(n/p,k/p-1) imes sum_{i=0}^{p-1}C_{n mod p}^i+C_{n/p}^{k/p} imes f(n mod p,k mod p))
(f(n/p,k/p-1))递归,(sum_{i=0}^{p-1}C_{n mod p}^i)预处理过了,(C_{n/p}^{k/p})直接lucas定理,(f(n mod p,k mod p))也预处理过了。
code:
#include<bits/stdc++.h>
using namespace std;
const long long p=2333;
int T,C[p+10][p+10],sum[p+10][p+10];
long long n,k;
int Lucas(long long x,long long y){//C_x^y
if(y>x)return 0;
if(x<=p&&y<=p)return C[x][y];
return Lucas(x/p,y/p)*C[x%p][y%p]%p;
}
int F(long long x,long long y){
if(y>x)y=x;
if(!y)return 1;
if(y<0)return 0;
if(x<=p&&y<=p)return sum[x][y];
return (F(x/p,y/p-1)*sum[x%p][p-1]%p+Lucas(x/p,y/p)*sum[x%p][y%p]%p)%p;
}
int main(){
C[0][0]=sum[0][0]=1;
for(int i=1;i<=p;++i)for(int j=0;j<=i;++j)C[i][j]=(C[i-1][j]+(j?C[i-1][j-1]:0))%p;
for(int i=0;i<=p;++i)for(int j=0;j<=p;++j)sum[i][j]=((j?sum[i][j-1]:0)+C[i][j])%p;
scanf("%d",&T);
while(T--)scanf("%lld%lld",&n,&k),printf("%d
",F(n,k));
return 0;
}