1. 程式人生 > >bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二類斯特林數 等比數列求和優化

bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二類斯特林數 等比數列求和優化

src algo names AI space efi get com name

[Tjoi2016&Heoi2016]求和

Time Limit: 40 Sec Memory Limit: 128 MB
Submit: 679 Solved: 534
[Submit][Status][Discuss]

Description

在2016年,佳媛姐姐剛剛學習了第二類斯特林數,非常開心。

現在他想計算這樣一個函數的值: 技術分享圖片 S(i, j)表示第二類斯特林數,遞推公式為: S(i, j) = j ∗ S(i − 1, j) + S(i − 1, j − 1), 1 <= j <= i − 1。 邊界條件為:S(i, i) = 1(0 <= i), S(i, 0) = 0(1 <= i) 你能幫幫他嗎?

Input

輸入只有一個正整數

Output

輸出f(n)。由於結果會很大,輸出f(n)對998244353(7 × 17 × 223 + 1)取模的結果即可。1 ≤ n ≤ 100000

Sample Input

3

Sample Output

87

HINT

Source

技術分享圖片

多謝大佬的blog,我自己寫比較慢,所以直接貼了。

這題本來是來練多項式求逆的,但是好像其它方法也可以做。

然後就通過這樣的方法解出了,我們都知道等比數列求和的第一項需要特殊考慮,所以g[1]=n

然後就是卷積的形式了,從n^2 log n-----------> n log n

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 
 7 #define ll long long
 8 #define mod 998244353
 9 #define G 3
10 #define N 100007
11 using namespace std;
12 inline int read()
13 {
14     int x=0,f=1
;char ch=getchar(); 15 while(!isdigit(ch)){if(ch==-)f=-1;ch=getchar();} 16 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-0;ch=getchar();} 17 return x*f; 18 } 19 20 int n,num,L,inv; 21 int jc[N],ny[N],jcn[N]; 22 ll a[N<<2],b[N<<2],rev[N<<2]; 23 24 int fast_pow(int a,int b) 25 { 26 int ans=1; 27 while(b) 28 { 29 if (b&1) ans=(ll)ans*a%mod; 30 a=(ll)a*a%mod; 31 b>>=1; 32 } 33 return ans; 34 } 35 void NTT(ll *a,ll f) 36 { 37 for (ll i=0;i<num;i++) 38 if (i<rev[i]) swap(a[i],a[rev[i]]); 39 for (ll i=1;i<num;i<<=1) 40 { 41 ll wn=fast_pow(G,(mod-1)/(i<<1)); 42 for (ll j=0;j<num;j+=(i<<1)) 43 { 44 ll w=1; 45 for (ll k=0;k<i;w=(ll)w*wn%mod,k++) 46 { 47 ll x=a[j+k],y=(ll)w*a[j+k+i]%mod; 48 a[j+k]=(x+y>=mod)?x+y-mod:x+y,a[j+k+i]=(x-y<0)?x-y+mod:x-y; 49 } 50 } 51 } 52 if (f==-1) 53 { 54 for (ll i=1;i<num/2;i++) swap(a[i],a[num-i]); 55 for (ll i=0;i<num;i++) a[i]=(ll)a[i]*inv%mod; 56 } 57 } 58 int main() 59 { 60 n=read(); 61 jc[0]=1,ny[0]=1,jcn[0]=1; 62 for (int i=1;i<=n;i++) 63 jc[i]=(ll)jc[i-1]*i%mod,ny[i]=fast_pow(i,mod-2),jcn[i]=(ll)jcn[i-1]*ny[i]%mod; 64 for (int i=0;i<=n;i++) 65 a[i]=(ll)((i&1)?-1:1)*jcn[i]; 66 for (int i=2;i<=n;i++) 67 b[i]=(ll)(fast_pow(i,n+1)-i)*jcn[i]%mod*ny[i-1]%mod;b[1]=n; 68 for (num=1;num<=2*n;num<<=1,L++);if (L) L--;inv=fast_pow(num,mod-2); 69 for (int i=0;i<=num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L); 70 NTT(a,1),NTT(b,1); 71 for (int i=0;i<num;i++) 72 a[i]=(ll)a[i]*b[i]%mod; 73 NTT(a,-1); 74 int ans=1;//第一項的等比數列的影響 75 for (int i=1;i<=n;i++) 76 (ans+=(ll)fast_pow(2,i)*jc[i]%mod*a[i]%mod)%=mod; 77 ans=(ans+mod)%mod; 78 printf("%d\n",ans); 79 }

bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二類斯特林數 等比數列求和優化