解题:HEOI 2016 求和
Posted ydnhaha
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解题:HEOI 2016 求和相关的知识,希望对你有一定的参考价值。
我们需要知道这样一个东西(大概叫 斯特林公式?)
$S(i,j)=frac{1}{j!}sumlimits_{k=0}^{j}(-1)^k C_j^k(j-k)^i$
那么就是推啊
$=sumlimits_{i=0}^nsumlimits_{j=0}^iS(i,j)*2^j*j!$
然后问题来了,因为后面还有$2^j$和$j!$,我们发现这里展开斯特林数也没用,所以我们要把它们甩出去
因为$j>i$时$S(i,j)==0$,所以让后面求和到$n$,然后前提$2^j$和$j!$
$=sumlimits_{i=0}^nsumlimits_{j=0}^nS(i,j)*2^j*j!$
$=sumlimits_{j=0}^n2^j*j!sumlimits_{i=0}^nS(i,j)$
展开斯特林数
$=sumlimits_{j=0}^n2^j*j!sumlimits_{i=0}^nfrac{1}{j!}sumlimits_{k=0}^{j}(-1)^k C_j^k(j-k)^i$
一般我们会把$C(j,k)$拆开来消掉前面的$frac{i}{j!}$
$=sumlimits_{j=0}^n2^j*j!sumlimits_{i=0}^nfrac{1}{j!}sumlimits_{k=0}^{j}(-1)^kfrac{j!}{k!(j-k)!}(j-k)^i$
$=sumlimits_{j=0}^n2^j*j!sumlimits_{i=0}^nsumlimits_{k=0}^{j}(-1)^kfrac{1}{k!(j-k)!}(j-k)^i$
那后面这个东西明显的分成了两部分:和$k$有关的和和$j-k$有关的
$=sumlimits_{j=0}^n2^j*j!sumlimits_{i=0}^nsumlimits_{k=0}^{j}frac{(-1)^k}{k!}frac{(j-k)^i}{(j-k)!}$
使用高中老师教给我们的等比数列求和公式
$=sumlimits_{j=0}^n2^j*j!sumlimits_{i=0}^nsumlimits_{k=0}^{j}frac{(-1)^k}{k!}frac{(j-k)^{i+1}-1}{(j-k-1)(j-k)!}$
这样和是一定的,所以用NTT卷出来后面的然后前面的$O(n)$求和就可以了
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=100005,mod=998244353; 6 int a[4*N],b[4*N],rev[4*N],fac[N],inv[N]; 7 int n,ni,G,Gi,pw,ans; 8 void exGCD(int a,int b,int &x,int &y) 9 { 10 if(!b) {x=1,y=0; return;} 11 exGCD(b,a%b,y,x),y-=a/b*x; 12 } 13 int Qpow(int x,int k) 14 { 15 if(!k) return 1; 16 if(k==1) return x; 17 int tmp=Qpow(x,k/2); 18 return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod; 19 } 20 int Inv(int x) 21 { 22 int xx,yy; 23 exGCD(x,mod,xx,yy); 24 return (xx%mod+mod)%mod; 25 } 26 void NTT(int *arr,int len,int typ) 27 { 28 for(int i=0;i<=len;i++) 29 if(rev[i]>i) swap(arr[rev[i]],arr[i]); 30 for(int i=2;i<=len;i<<=1) 31 { 32 int lth=i>>1,ort=Qpow(~typ?G:Gi,(mod-1)/i); 33 for(int j=0;j<len;j+=i) 34 { 35 int ori=1,tmp; 36 for(int k=j;k<j+lth;k++,ori=1ll*ori*ort%mod) 37 { 38 tmp=1ll*ori*arr[k+lth]%mod; 39 arr[k+lth]=(arr[k]-tmp+mod)%mod; 40 arr[k]=(arr[k]+tmp)%mod; 41 } 42 } 43 } 44 if(typ==-1) 45 { 46 int ni=Inv(len); 47 for(int i=0;i<=len;i++) 48 arr[i]=1ll*arr[i]*ni%mod; 49 } 50 } 51 void Init() 52 { 53 scanf("%d",&n); 54 G=3,Gi=Inv(G),fac[0]=inv[0]=pw=1; 55 for(int i=1;i<=n;i++) 56 fac[i]=1ll*fac[i-1]*i%mod; 57 inv[n]=Inv(fac[n]); 58 for(int i=n-1;i;i--) 59 inv[i]=1ll*inv[i+1]*(i+1)%mod; 60 for(int i=0;i<=n;i++) 61 a[i]=(i%2)?mod-inv[i]:inv[i]; b[0]=1,b[1]=n+1; 62 for(int i=2;i<=n;i++) 63 b[i]=1ll*(Qpow(i,n+1)-1)*Inv(i-1)%mod*inv[i]%mod; 64 } 65 void Prework() 66 { 67 int len=1; while(len<=2*n+2) len<<=1; 68 for(int i=1;i<=len;i++) 69 rev[i]=(rev[i>>1]>>1)+(i&1)*(len>>1); 70 NTT(a,len,1),NTT(b,len,1); 71 for(int i=0;i<=len;i++) a[i]=1ll*a[i]*b[i]%mod; 72 NTT(a,len,-1); 73 } 74 int main() 75 { 76 Init(),Prework(); 77 for(int i=0;i<=n;i++,pw=pw*2%mod) 78 ans+=1ll*pw*fac[i]%mod*a[i]%mod,ans%=mod; 79 printf("%d",ans); 80 return 0; 81 }
以上是关于解题:HEOI 2016 求和的主要内容,如果未能解决你的问题,请参考以下文章
[BZOJ4555][TJOI2016&HEOI2016]求和(分治FFT)