bzoj4591 Shoi2015超能粒子炮·改

Posted Czarina

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4591 Shoi2015超能粒子炮·改相关的知识,希望对你有一定的参考价值。

由Lucas定理C(n,k)=C(n/2333,k/2333)*C(n%2333,k%2333)%2333

则ans=ΣC(n,i),(i<=k)

    =C(n/2333,0)*C(n%2333,0)+C(n/2333,1)*C(n%2333,1)+...+C(n/2333,2332)

    +C(n/2333,0)*C(n%2333,0)+C(n/2333,1)*C(n%2333,1)+...+C(n/2333,2332)

    =∑C(n/2333,j)*sum[n%2333][2332]+C(n/2333,k/2333)*sum[n%2333][k%2333],(0<=j<k/2333)

cal(n,k)=cal(n/2333,k/2333-1)*sum[n%2333][2332]+Lucas(n/2333,k/2333)*sum[n%2333][k%2333]

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define int long long
using namespace std;
const int p=2333;
int T,c[p+10][p+10],sum[p+10][p+10];
int Lucas(int a,int b)
{
    if(a<0||b<0) return 0;
    if(a<p&&b<p) return c[a][b];
    return Lucas(a/p,b/p)*c[a%p][b%p]%p;
}
int cal(int n,int k)
{
    if(k<0) return 0;
    return (cal(n/p,k/p-1)*sum[n%p][p-1]+Lucas(n/p,k/p)*sum[n%p][k%p])%p;
}
void pre()
{
    c[0][0]=1;sum[0][0]=1; for(int i=1;i<p;i++) c[i][0]=1,sum[i][0]=1,sum[0][i]=1;
    for(int i=1;i<p;i++) for(int j=1;j<=i;j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%p;
    for(int i=1;i<p;i++) for(int j=1;j<p;j++) sum[i][j]=sum[i][j-1]+c[i][j];
}
signed main()
{
    pre();
    scanf("%lld",&T);
    while(T--)
    {
        int n,k;
        scanf("%lld%lld",&n,&k);
        printf("%lld\n",cal(n,k));
    }
    return 0;
}

 

以上是关于bzoj4591 Shoi2015超能粒子炮·改的主要内容,如果未能解决你的问题,请参考以下文章

BZOj-4591: [Shoi2015]超能粒子炮·改 (Lucas+排列组合)

BZOj-4591: [Shoi2015]超能粒子炮·改 (Lucas+排列组合)

bzoj4591[Shoi2015]超能粒子炮·改 Lucas定理

Bzoj 4591: [Shoi2015]超能粒子炮·改 数论,Lucas定理,排列组合

[bzoj4591] [Shoi2015]超能粒子炮·改

bzoj4591 / P4345 [SHOI2015]超能粒子炮·改