變換
可以用等比數列求和公式++求得
對於無標號有根樹的生成函數,可以列出方程:
分治
也即
因爲有,所以我們可以對兩邊求導得到:
兩邊同時
另
可以發現
然後就可以分治了。
牛頓迭代
考慮計算
當然也可以求
是的,就是,儘管他的表達式裏有
注意這裏常數項爲。
設
可以對牛頓迭代:
發現上面的雖然算不出來,但是他抵消了。
多項式牛頓迭代:
#include<bits/stdc++.h>
#define mod 998244353
#define maxn 550005
#define LL long long
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
using namespace std;
int Wl,Wl2,w[maxn],lg[maxn],inv[maxn],fac[maxn],invf[maxn];
int Pow(int b,int k){ int r=1;for(;k;k>>=1,b=1ll*b*b%mod) if(k&1) r=1ll*r*b%mod;return r; }
void init(int n){
for(Wl=1;n>=Wl<<1;Wl<<=1);int pw=Pow(3,(mod-1)/(Wl2=Wl<<1));
w[Wl] = 1;
rep(i,Wl+1,Wl2-1) w[i] = 1ll * w[i-1] * pw % mod;
per(i,Wl-1,1) w[i] = w[i<<1];
fac[0] = fac[1] = inv[0] =inv[1] = invf[0] = invf[1] = 1;
rep(i,2,Wl2) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod , fac[i] = 1ll * fac[i-1] * i % mod,
invf[i] = 1ll * invf[i-1] * inv[i] % mod , lg[i] = lg[i>>1] + 1;
}
int upd(int x){ return x += x >> 31 & mod; }
void NTT(int *A,int n,int tp){
static int r[maxn];
static unsigned long long ar[maxn];
if(tp^1) reverse(A+1,A+n);
rep(i,0,n-1) r[i] = r[i>>1]>>1|(i&1)<<lg[n]-1,ar[i]=upd(A[r[i]]);
for(int L=1;L<n;L<<=1) for(int s=0,L2=L<<1;s<n;s+=L2) for(int k=s,x=L,t;k<s+L;k++,x++)
t=w[x]*ar[k+L]%mod,ar[k+L]=ar[k]-t+mod,ar[k]+=t;
rep(i,0,n-1) A[i]=ar[i]%mod;
if(tp^1) rep(i,0,n-1) A[i] = 1ll * A[i] * inv[n] % mod;
}
void Mul(int *A,int *B,int *C,int n,int m){
static int st[2][maxn];
if(1ll * n * m <= 1000){
rep(i,0,n+m){
int j=0,L=min(n,i);
st[0][i] = 0;
for(;j+7<=L;j+=8)
st[0][i] = (st[0][i]
+ (LL)A[j] * B[i-j]
+ (LL)A[j+1] * B[i-j-1]
+ (LL)A[j+2] * B[i-j-2]
+ (LL)A[j+3] * B[i-j-3]
+ (LL)A[j+4] * B[i-j-4]
+ (LL)A[j+5] * B[i-j-5]
+ (LL)A[j+6] * B[i-j-6]
+ (LL)A[j+7] * B[i-j-7]
) % mod;
for(;j<=L;j++)
st[0][i] = (st[0][i] + (LL) A[j] * B[i-j]) % mod;
}
rep(i,0,n+m) C[i] = st[0][i];
return;
}
int L = 1 << lg[n+m] + 1;
rep(i,0,L-1) st[0][i] = i <= n ? A[i] : 0,
st[1][i] = i <= m ? B[i] : 0;
NTT(st[0],L,1),NTT(st[1],L,1);
rep(i,0,L-1) C[i] = 1ll * st[0][i] * st[1][i] % mod;
NTT(C,L,-1);
}
void Inv(int *A,int *B,int n){
B[B[1]=0]=Pow(A[0],mod-2);
static int t[maxn];
for(int k=2,L=4;k<(n<<1);k<<=1,L<<=1){
rep(i,0,L-1) t[i]=i<k?A[i]:B[i]=0;
NTT(t,L,1),NTT(B,L,1);
rep(i,0,L-1) B[i]=upd(B[i]*(2-1ll*t[i]*B[i]%mod)%mod);
NTT(B,L,-1);
rep(i,min(n,k),L-1) B[i] =0;
}
}
int n,A[maxn];
void Solve(int *A,int n){
static int st[3][maxn];
A[0]=1;
for(int k=2,L=4;k<(n<<1);k<<=1,L<<=1){
Inv(A,st[0],k);
rep(i,0,k-1) st[1][i] = A[i+1] * (i+1ll) % mod;
Mul(st[1],st[0],st[1],k-1,k-1);
per(i,k-1,1) st[1][i] = 1ll * st[1][i-1] * inv[i] % mod;
st[1][0] = 0;
rep(i,1,k-1) for(int j=i,p=0;j<=k;j+=i,p++)
st[1][j] = (st[1][j] - 1ll * A[p] * inv[i]) % mod;
st[0][1] --;
Inv(st[0],st[2],k);
Mul(st[2],st[1],st[1],k-1,k-1);
rep(i,0,min(n-1,k-1)) A[i] = upd(A[i] - st[1][i]);
}
per(i,n,1) A[i] = A[i-1];
A[0] = 0;
}
int main(){
freopen("1.in","r",stdin);
scanf("%d",&n);
init(n<<1);
Solve(A,n+1);
int ans = A[n];
rep(i,n/2+1,n-1) ans = (ans - 1ll * A[i] * A[n-i]) % mod;
if(n%2==0) ans = (ans - 1ll * A[n/2] * (A[n/2] - 1) / 2) % mod;
printf("%d\n",(ans+mod)%mod);
}