zoukankan      html  css  js  c++  java
  • 【题解】P4091 [HEOI2016/TJOI2016]求和

    【题解】P4091 [HEOI2016/TJOI2016]求和

    [P4091 HEOI2016/TJOI2016]求和

    可以知道(i,j)(0)开始是可以的,因为这个时候等于(0)。这种题目都要从(0)开始或许比较好(Itst语)

    然后就开始化式子吧

    原式=

    [sum_{i=0}^{n} sum_{j=0}^n {i race j}2^j j! ]

    斯特林容斥式子展开一下,并且我们知道当(k>j)时,({j choose k}=0),所以扩大枚举范围到(n)

    [sum_{i=0}^nsum_{j=0}^n j!sum_{k=0}^n dfrac 1 {j!}(-1)^k{j choose k}(j-k)^i ]

    只有一项和(i)有关,约掉一些东西

    [sum_{j=0}^nsum_{k=0}^j (-1)^k{j choose k}sum_{i=0}^n(j-k)^i ]

    等比求和(边界情况到时候再考虑)

    [sum_{j=0}^n sum_{k=0}^j (-1)^k{j choose k}dfrac {1-(j-k)^{n+1}} {1-(j-k)} ]

    拆掉组合数

    [sum_{j=0}^n j! sum_{k=0}^j dfrac{(-1)^k} {k!}dfrac {1-(j-k)^{n+1}} {1-(j-k)} ]

    就是一个(NTT)的式子,(NTT)处理就好了。

    这题关键就是想到那个...算了没什么关键的,无非就是记得几个公式。

    其实关键的就是记得把枚举下标最好扩展到一起,来消除变量之间的相互联系,并且方便预处理。

    考虑一些边界:

    (j-k=0)的时候,此时(j=k),代回到最开始发现要(=1),或者说一般组合题里面认为(0^0=1)

    (j-k=1)的时候,这个时候简单一点,就是等比数列不能用公式的情况,直接(=n+1)即可。

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    
    using namespace std;  typedef long long ll;
    inline int qr(){
          register int ret=0,f=0;
          register char c=getchar();
          while(c<48||c>57)f|=c==45,c=getchar();
          while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
          return f?-ret:ret;
    }
    
    namespace poly{
          const int maxn=1<<21|1;
          int r[maxn];
          int savlen;
          inline void getr(const int&len){
    	    if(len==savlen) return;
    	    int cnt=0;
    	    for(register int t=1;t<len;t<<=1)++cnt;
    	    for(register int t=1;t<len;++t)
    		  r[t]=r[t>>1]>>1|(t&1)<<cnt>>1;
          }
          const int mod=998244353;
          const int g=3;
          const int gi=332748118;
          inline int ksm(const int&base,const int&p){
    	    register int ret=1;
    	    for(register int t=p,b=base%mod;t;t>>=1,b=1ll*b*b%mod)
    		  if(t&1) ret=1ll*ret*b%mod;
    	    return ret;
          }
          inline void NTT(int*a,const int&len,const int&tag){
    	    getr(len);
    	    for(register int t=1;t<len;++t)
    		  if(r[t]>t) swap(a[t],a[r[t]]);
    	    int *a0,*a1,s=g;
    	    if(tag!=1) s=gi;
    	    for(register int t=1,wn;t<len;t<<=1){
    		  wn=ksm(s,(mod-1)/(t<<1));
    		  for(register int i=0;i<len;i+=t<<1){
    			a1=(a0=a+i)+t;
    			for(register int k=0,m,w=1;k<t;++k,++a1,++a0,w=1ll*w*wn%mod){
    			      m=1ll*w**a1%mod;
    			      *a1=(*a0+mod-m)%mod;
    			      *a0=(*a0+m)%mod;
    			}
    		  }
    	    }
    	    if(tag!=1)
    	    for(register int t=0,w=ksm(len,mod-2);t<len;++t)
    		  a[t]=1ll*a[t]*w%mod;
          }
    }
    
    using namespace poly;
    int jc[100005],inv[100005],bin[100005],n;
    
    inline void pre(){
          bin[0]=jc[0]=inv[0]=1;
          for(register int t=1;t<=100000;++t)
    	    jc[t]=1ll*jc[t-1]*t%mod;
          inv[100000]=ksm(jc[100000],mod-2);
          for(register int t=100000-1;t;--t)
    	    inv[t]=1ll*(t+1)*inv[t+1]%mod;
          for(register int t=1;t<=100000;++t)
    	    bin[t]=(bin[t-1]<<1)%mod;
          
    }
    
    
    int a[maxn],b[maxn];
    int main(){
    #ifndef ONLINE_JUDGE
          freopen("in.in","r",stdin);
    #endif
          pre();
          n=qr();
          for(register int t=0;t<=n;++t){
    	    a[t]=inv[t];
    	    if(t&1) a[t]=mod-a[t];
    	    b[t]=1ll*(ksm(t,n+1)-1ll+mod)%mod*ksm(t-1,mod-2)%mod*inv[t]%mod;
          }
          b[0]=1;b[1]=n+1;
          int k=1;
          while(k<=n)k<<=1;
          NTT(a,k<<1,1);NTT(b,k<<1,1);
          for(register int t=0;t<k<<1;++t) a[t]=1ll*a[t]*b[t]%mod;
          NTT(a,k<<1,-1);
          int ans=0;
          for(register int t=0;t<=n;++t)
    	    ans=(ans+1ll*bin[t]*jc[t]%mod*a[t]%mod)%mod;
          cout<<ans<<endl;
          return 0;
    }
    
    
  • 相关阅读:
    SharePoint 集成OWA概述
    SharePoint Online 创建和使用栏
    SharePoint Online 创建资产库
    SharePoint Online 创建图片库
    SharePoint Online 创建文档库
    SharePoint Online 创建列表库
    SharePoint Online 设置网站集
    SharePoint Online 创建网站集
    SharePoint Online 创建用户和组
    【BLE】CC2541之发现服务与特征值
  • 原文地址:https://www.cnblogs.com/winlere/p/11204007.html
Copyright © 2011-2022 走看看