bzoj4555(斯特林數,NTT)
阿新 • • 發佈:2018-12-22
Description
在2016年,佳媛姐姐剛剛學習了第二類斯特林數,非常開心。
現在他想計算這樣一個函式的值:f(n)=ΣiΣj s(i,j)*2^j* j!
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
:
要求
可以等價於求
後面推式子就行了
後面那個式子是個卷積的形式
直接
就行了
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back
#define pc putchar
#define mp make_pair
#define file(k) memset(k,0,sizeof(k))
#define ll long long
int rd()
{
int num = 0;char c = getchar();bool flag = true;
while(c < '0'||c > '9') {if(c == '-') flag = false;c = getchar();}
while(c >= '0' && c <= '9') num = num*10+c-48,c = getchar();
if(flag) return num;else return -num;
}
const int p = 998244353,g = 3;
inline int ksm(int a,int x){int now = 1;for(;x;x>>=1,a=1ll*a*a%p)if(x&1)now=1ll*now*a%p;return now;}
inline int calc(int a,int b){return (a+=b)>=p?a-=p:a;}
inline int del(int a,int b){return (a-=b)<0?a+=p:a;}
inline int mul(int a,int b){return 1ll*a*b%p;}
int n;
int r[401000],w[401000];
int fac[101000],inv[101000];
int a[401000],b[401000];
void ntt(int *a,int f,int flen)
{
w[0] = 1;
rep(i,0,flen-1) r[i] = (r[i>>1]>>1) | ((i&1)?flen/2:0);
rep(i,0,flen-1) if(i < r[i]) swap(a[i],a[r[i]]);
for(int len = 2;len <= flen;len<<=1)
{
int wn = ksm(g,(p-1)/len);
if(f == -1) wn = ksm(wn,p-2);
rep(i,1,len-1) w[i] = mul(w[i-1],wn);
for(int st = 0;st < flen;st += len)
rep(i,0,len/