Processing math: 100%

显然,题目需要我们求出:

ki=0Cinmod2333

其中 n1018 。直接暴力求显然会炸掉,感觉当前的式子不是很好做,推推式子看看。

首先 2333 是质数,这个时候看到了组合数,应该是可以想到 Lucas 定理的,我们将 Lucas 套上去 (并且令 p2333) ,并且设答案为 f(n,k)
f(n,k)=ki=0Cinmodp=ki=0Ci%pn%pCi/pn/pmodp=p1x=0Cxn%pki=0[i%p=x]Ci/pn/pmodp=C0n/pp1x=0Cxn%p+C1n/pp1x=0Cxn%pCk/pn/pk%px=0Cxn%pmodp=k/p1i=0Cin/pp1x=0Cxn%p+Ck/pn/pk%px=0Cxn%pmodp=f(n/p,k/p1)f(n%p,p1)+Ck/pn/pf(n%p,k%p)modp


于是最终得到了答案,递归处理即可。

Code:

#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;

const int N=2333+2;
#define p 2333

ll n,k,f[N][N],c[N][N];

template <typename _Tp> inline void IN(_Tp&x) {
    char ch;bool flag=0;x=0;
    while(ch=getchar(),!isdigit(ch)) if(ch=='-') flag=1;
    while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    if(flag) x=-x;
}

ll lucas(ll n,ll m) {
    if(!m||n==m) return 1;
    if(n<m) return 0;
    if(n<p&&m<p) return c[n][m];
    return c[n%p][m%p]*lucas(n/p,m/p)%p;
}
ll F(ll n,ll k) {
    if(k<0) return 0;
    if(!n||!k) return 1;
    if(n<p&&k<p) return f[n][k];
    return (F(n/p,k/p-1)*f[n%p][p-1]%p+lucas(n/p,k/p)*f[n%p][k%p]%p)%p;
}

int main() {
    for(int i=0;i<=p;++i) c[i][0]=c[i][i]=1,f[i][0]=1;
    for(int i=1;i<=p;++i) 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<=p;++i) for(int j=1;j<=p;++j)
        f[i][j]=(f[i][j-1]+c[i][j])%p;
    int t;IN(t);
    while(t--) {
        IN(n),IN(k);
        printf("%lld\n",F(n,k));
    }
    return 0;
}
C++
分类: 文章

Qiuly

QAQ

0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注