P4345 [SHOI2015] 超能粒子炮·改 Lucas定理

发布时间 2023-09-04 22:24:46作者: chdy

求解\(\sum_{i=0}^kC(n,i)\mod 2333\)

值得一提的是\(2,23,233,2333\)均为质数。

这次是对行求和。并没有很难好的公式。

但是由于模数非常特殊可以使用卢卡斯定理。

\(C(n,i)\%\ p=C(n\%p,i\%p)\cdot C(n/p,i/p)\)

不妨设\(f(n,k)=\sum_{i=0}^kC(n,i)\%\ 2333\)

原式\(=\sum_{i=0}^kC(n\%p,i\%p)\cdot C(n/p,i/p)\)

注意边界可以递归运算。

注意预处理加快速度。

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x)
#define putl_(x) printf("%lld ",x)
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;i+=1)
#define fep(n,p,i) for(int i=n;i>=p;--i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define ui unsigned
#define sq sqrt
#define x(w) t[w].x
#define r(w) t[w].r
#define id(w) t[w].id
#define R(w) s[w].r
#define yy p<<1|1
#define zz p<<1
#define sum(w) t[w].sum
#define mod 2333
#define sc(A) scanf("%d",&A)
#define scl(A) scanf("%lld",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define sub(x,y) (x-y<0?x-y+mod:x-y)
#define uint unsigned int
using namespace std;
const int MAXN=30010,G=3;
int T;
int fac[MAXN],inv[MAXN];
int w[2334][2334];
inline int ksm(int b,int cc)
{
	int cnt=1;
	while(cc)
	{
		if(cc&1)cnt=cnt*b%mod;
		b=b*b%mod;cc=cc>>1;
	}
	return cnt;
}
inline int C(int n,int m){return m>n?0:fac[n]*inv[m]%mod*inv[n-m]%mod;}
inline int sol(ll n,ll k)
{
	if(n<mod)return C(n,k);
	return sol(n/mod,k/mod)*sol(n%mod,k%mod)%mod;
}
inline int solve(ll n,ll k)
{
	if(k<0)return 0;
	if(n<mod)return w[n][min(n,k)];
	if((k+1)%mod==0)return solve(n%mod,mod-1)*solve(n/mod,k/mod)%mod;
	return (solve(n%mod,mod-1)*solve(n/mod,k/mod-1)%mod+solve(n%mod,k%mod)*sol(n/mod,k/mod)%mod)%mod;
}
int main()
{
	//freopen("1.in","r",stdin);
	sc(T);
	fac[0]=1;
	rep(1,mod-1,i)fac[i]=fac[i-1]*i%mod;
	inv[mod-1]=ksm(fac[mod-1],mod-2);
	fep(mod-2,0,i)inv[i]=inv[i+1]*(i+1)%mod;
	rep(0,mod-1,i)
	{
		rep(0,i,j)
		{
			w[i][j]=C(i,j);
			if(j)w[i][j]=(w[i][j]+w[i][j-1])%mod;
		}
	}
	while(T--)
	{
		ll n,k;
		scl(n);scl(k);
		put(solve(n,k));
	}
	return 0;
}