zoukankan      html  css  js  c++  java
  • Luogu P4091 [HEOI2016/TJOI2016]求和

    Link

    [egin{aligned} ans&=sumlimits_{i=0}^nsumlimits_{j=0}^ileft{iatop j ight}2^jj!\ &=sumlimits_{i=0}^nsumlimits_{j=0}^nleft{iatop j ight}2^jj!\ &=sumlimits_{i=0}^nsumlimits_{j=0}^n2^jsumlimits_{k=0}^j(-1)^{j-k}{jchoose k}k^i\ &=sumlimits_{i=0}^nsumlimits_{j=0}^n2^jsumlimits_{k=0}^j(-1)^{j-k}{jchoose k}k^i\ &=sumlimits_{j=0}^nsumlimits_{k=0}^j(-1)^{j-k}{jchoose k}2^j[n+1]_k\ &=sumlimits_{k=0}^n[n+1]_ksumlimits_{i=k}^n(-1)^{i-k}{ichoose k}2^i\ &=sumlimits_{k=0}^n(-1)^k[n+1]_ksumlimits_{i=k}^n(-2)^i{ichoose k}end{aligned} ]

    (a_i=sumlimits_{j=i}^n(-2)^j{jchoose i}),那么(ans=sumlimits_{k=0}^n(-1)^k[n+1]_ka_k)
    ([n+1]_k)是可以利用线性筛求出来的,那么我们现在考虑如何线性求出(a)
    (a_0)是可以轻松线性计算的,那么我们考虑递推。

    [egin{aligned} a_i&=sumlimits_{j=i}^n(-2)^j{jchoose i}\ &=sumlimits_{j=i}^n(-2)^j({j-1choose i}+{j-1choose i-1})\ &=(-2)(sumlimits_{j=i}^{n-1}(-2)^j{jchoose i}+sumlimits_{j=i-1}^{n-1}(-2)^j{jchoose i-1})\ &=-2(a_i+a_{i-1})+2(-2)^n{n+1choose i}\ &=frac23((-2)^n{n+1choose i}-a_{i-1}) end{aligned} ]

    很显然预处理阶乘就可以线性计算了。

    #include<cstdio>
    const int N=100007,P=998244353;
    int fac[N],ifac[N],inv[N],pw[N],is[N],pr[N],pw2[N],a[N];
    void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
    void dec(int&a,int b){a-=b,a+=a>>31&P;}
    int mul(int a,int b){return 1ll*a*b%P;}
    int pow(int a,int b){int r=1;for(;b;b>>=1,a=mul(a,a))if(b&1)r=mul(a,r);return r;}
    int C(int n,int m){return 1ll*fac[n]*ifac[n-m]%P*ifac[m]%P;}
    int main()
    {
        int n,m=0,ans=0;scanf("%d",&n),fac[0]=fac[1]=ifac[0]=ifac[1]=inv[0]=inv[1]=pw2[0]=1,pw2[1]=P-2;
        for(int i=2;i<=n;++i)
        {
    	if(!is[i]) pr[++m]=i,pw[i]=pow(i,n+1);
    	for(int j=1;pr[j]*i<=n;++j){is[i*pr[j]]=1,pw[i*pr[j]]=mul(pw[i],pw[pr[j]]);if(!(i%pr[j]))break;}
        }
        for(int i=2;i<=n+3;++i) fac[i]=mul(fac[i-1],i),ifac[i]=mul(ifac[i-1],inv[i]=mul(P-P/i,inv[P%i])),pw2[i]=mul(pw2[i-1],P-2);
        for(int i=0;i<=n;++i) inc(a[0],pw2[i]);
        for(int i=1;i<=n;++i) a[i]=2ll*inv[3]*(1ll*pw2[n]*C(n+1,i)%P-a[i-1]+P)%P;
        for(int i=2;i<=n;++i) (i&1? dec:inc)(ans,(pw[i]-1ll)*a[i]%P*inv[i-1]%P);
        inc(ans,a[0]),dec(ans,mul(a[1],n+1)),printf("%d",ans);
    }
    
  • 相关阅读:
    153. Find Minimum in Rotated Sorted Array
    228. Summary Ranges
    665. Non-decreasing Array
    661. Image Smoother
    643. Maximum Average Subarray I
    4.7作业
    面向对象编程
    常用模块3
    3.31作业
    常用模块2
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12745428.html
Copyright © 2011-2022 走看看