【JZOJ 5395】【NOIP2017提高A组模拟10.6】Count

来源:互联网 发布:淘宝自动装修软件 编辑:程序博客网 时间:2024/05/21 04:25

Descrption

这里写图片描述

Solution

Ans=i=lrik

也就是求出Ans=ni=1ik即可,

这个Ans肯定可以表示成一个k+1的多项式,

——(以下为证明,大佬跳过)——-
设多项式L(x)=ni=1ik
那么,L(x+1)=(x+1)k+L(x)
我们发现,只有当L为k+1的多项式时,才可以化简出一个(x+1)k
——(好辣鸡的证明啊~)——

那么用拉格朗日插值法即可直接做,预处理前k+2个数,在最后的式子你会发现其只是一堆连续的数求积,直接预处理即可,

复杂度:O(m)

Code

#include <cstdio>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;typedef long long LL;const int N=1000010,mo=998244353;int m,n,n1,M;bool prz[N];int pr[N/5];int Ans[N];LL ALLc,Pi[N];LL ksm(LL q,int w){    LL ans=1;    for(;w;w>>=1,q=q*q%mo)if(w&1)ans=ans*q%mo;    return ans;}LL LIP(int n){    if(n<1)return 0;    if(n<=m)return Ans[n];    ALLc=1;    fo(i,n-m,n-1)ALLc=ALLc*(LL)i%mo;    LL ans=0;    fo(i,1,m)    {        LL t1=Pi[i-1]*Pi[m-i]%mo*(LL)(n-i)%mo;        if((m-i+2)&1)t1=-t1;        ans=(ans+Ans[i]*ksm(t1,mo-2)%mo)%mo;    }    if(ans<0)ans+=mo;    return ans*ALLc%mo;}int main(){    scanf("%d%d%d",&n,&n1,&m);    M=m;m+=2;    Ans[1]=Pi[0]=Pi[1]=1;    fo(i,2,m)    {        if(!prz[i])pr[++pr[0]]=i,Ans[i]=ksm(i,M);        fo(j,1,pr[0])        {            int t=pr[j]*i;            if(t>m||t<1)break;            prz[t]=1;            Ans[t]=Ans[i]*(LL)Ans[pr[j]]%mo;            if(i%pr[j]==0)break;        }        Pi[i]=Pi[i-1]*(LL)i%mo;    }    fo(i,2,m+2)Ans[i]=(Ans[i]+Ans[i-1])%mo;    printf("%lld\n",((n<2?(n=2,ksm(2,M)):0)+LIP(n1)-LIP(n-1)+mo)%mo);    return 0;}
阅读全文
0 0
原创粉丝点击