4591: [Shoi2015]超能粒子炮·改

这个题目。。。

题意:求$\Large{\sum^k_{i=0}C_n^i\%2333}$

dalao讲的

令$\Large{p=2333,sum[i][j]=\sum_{k=1}^jC_i^k}$

则$\Large{ans=\sum_{i=0}^kC_n^i}$

         $\Large{=\sum_{i=0}^n(C_{n\%p}^{i\%p}*C_{n/p}^{i/p})}$
         $\Large{=\sum_{i=0}^{\frac{k}{p}-1}(C_{n/p}^i*\sum{_{j=0}^{p-1}C_{n\%p}^j})+C_{n/p}^{k/p}*\sum_{i=0}^{k\%p}C_{n\%p}^i}$
         $\Large{=\sum_{i=0}^{\frac{k}{p}-1}(C_{n/p}^i*S[n\%p][p-1])+C_{n/p}^{k/p}*S[n\%p][k\%p]}$
         $\Large{=S[\frac{n}{p}][\frac{k}{p}-1]*S[n\%p][p-1]+C_{n/p}^{k/p}*S[n\%p][k\%p]}$

n,k小于p的S可以预处理,C可以卢卡斯算

#include<cstdio>
#include<iostream>
#include<cctype>
using namespace std;
#define love_nmr 0;
#define nmr 2333
#define int long long 
int t;
int n;
int k;
int fac[2363];
int inv[2363];
int sum[2363][2363];
inline int read()
{
    int f=1,x=0;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            f=-f;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
inline void put(int x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
        put(x/10);
    putchar(x%10+'0');
}

inline int ksm(int x,int y)
{
    int re=1LL;
    while(y)
    {
        if(y&1)
            re=re*x%nmr;
        x=x*x%nmr;
        y>>=1;
    }
    return re;
}
inline int lucas(int x,int y)
{
    if(!y)  return 1;
    if(y>x)  return 0;
    if(y<nmr&&x<nmr)
        return fac[x]*inv[x-y]%nmr*inv[y]%nmr;
    return lucas(x%nmr,y%nmr)*lucas(x/nmr,y/nmr)%nmr;

}
inline void init()
{
    fac[0]=inv[0]=inv[1]=sum[0][0]=1;
    for(int i=1;i<nmr;i++)
        fac[i]=fac[i-1]*i%nmr;
    for(int i=2;i<nmr;i++)
        inv[i]=(nmr-nmr/i)*inv[nmr%i]%nmr;
    for(int i=1;i<nmr;i++)
        (inv[i]*=inv[i-1])%=nmr;
    for(int i=0;i<nmr;i++)
    { 
        sum[i][0]=1;
        for(int j=1;j<nmr;j++)
            sum[i][j]=(sum[i][j-1]+lucas(i,j))%nmr;
    }

}
inline int calc(int x,int y)
{
    if(y<0) return 0;
    int re=0;
    (re+=calc(x/nmr,y/nmr-1)*sum[x%nmr][nmr-1]%nmr)%=nmr;
    (re+=lucas(x/nmr,y/nmr)*sum[x%nmr][y%nmr]%nmr)%=nmr;
    return re;
}
signed main()
{
    t=read();
    init();
    while(t--)
    {
        n=read();
        k=read();
        put(calc(n,k)%nmr);
        putchar('\n');
    }
}

猜你喜欢

转载自www.cnblogs.com/olinr/p/9425369.html