AT_agc063_e Child to Parent 题解
AT_agc063_e Child to Parent 题解
设 \(c_x\) 表示点 \(x\) 一共执行的操作次数,对于不同的 \(c_x\) 序列最终的 \(A\) 序列是不同的,因此我们对 \(c_x\) 序列计数即可。
容易发现一个 \(c_x\) 合法的充要是 \(0\le c_x\le A_x+R\times \sum _{v\in son(x)} c_v\),但是我们不能把 \(c_x\) 记进状态里。
尝试设 DP \(f_x\) 表示子树 \(x\) 内的答案,假如我们求出了子树 \(x\) 内所有方案的 \(c_x\) 的和 \(g_x\),那么容易转移出 \(f_x\),有:
\[f_x=(A_x+1)(\prod_{v\in son(x)} f_v)+\sum _{v\in son(x)} g_v\prod _{w\in son(x)\setminus v} f_w
\]
但是这个转移没有什么用,考虑设 \(f_{x,i}\) 表示子树 \(x\) 内所有方案的 \(c_x^i\) 的和,而方案数就相当于 \(f_{x,0}\),我们的最终答案即 \(f_{1,0}\)。可以写出转移(设 \(lim=A_x+R\times \sum c_v\)):
\[f_{x,i}=\sum _{所有方案} \sum _{t=0}^{lim} t^i
\]
用第二类斯特林数将普通幂转下降幂,得:
\[\begin{aligned}
f_{x,i} &= \sum _{所有方案} \sum _{t=0}^{lim} \sum _{j=0}^{i} {i\brace j}j!\binom {t}{j} \\
&= \sum _{所有方案} \sum _{j=0}^i {i\brace j} j!\sum _{t=0}^{lim} \binom{t}{j}\\
&= \sum _{所有方案} \sum _{j=0}^{i}{i\brace j} j!\binom {lim+1}{j+1} \\
&= \sum _{所有方案} \sum _{j=0}^{i} {i\brace j} \frac{(lim+1)^{\underline{j+1}}}{j+1}
\end{aligned}
\]
只需求出所有方案的 \((A_x+R\times \sum c_v+1)^{\underline {j+1}}\) 的和即可。拆出来是关于 \(\sum c_v\) 的多项式,而处理所有方案下 \((\sum c_v)^j\) 的和可以每次用二项式定理合并一个儿子。
复杂度是 \(O(n^3)\)。
代码:
const int N=305,mod=998244353;
void inc(int &x,int y) {x+=y; if(x>=mod) x-=mod;}
void dec(int &x,int y) {if(x<y) x+=mod-y; else x-=y;}
int add(int x,int y) {return x+y>=mod ? x+y-mod : x+y;}
int sub(int x,int y) {return x<y ? x-y+mod : x-y;}
int mul(int x,int y) {return (ull) x*y%mod;}
int pow1(int x,int y) {
int res=1;
for(;y;y>>=1,x=mul(x,x)) if(y&1) res=mul(res,x);
return res;
}
vi mul(const vi &x,const vi &y) {
vi nw(Size(x)+Size(y)-1);
fu(i,0,Size(x)) fu(j,0,Size(y)) inc(nw[i+j],mul(x[i],y[j]));
return nw;
}
int str[N][N],C[N][N],inv[N];
int f[N][N],g[N],n,A[N],R;
vi G[N];
void dfs(int x) {
f[x][0]=1;
for(int v:G[x]) {
dfs(v);
memset(g,0,sizeof g);
fo(i,0,n) {
fo(j,0,i) {
inc(g[i],mul(C[i][j],mul(f[x][j],f[v][i-j])));
}
}
memcpy(f[x],g,sizeof g);
}
if(x==1) return;
memset(g,0,sizeof g);
vi p{1};
fo(j,0,n) {
p=mul(p,vi{sub(add(A[x],1),j),R});
int s=0;
fu(i,0,Size(p)) inc(s,mul(f[x][i],p[i]));
s=mul(s,inv[j+1]);
fo(i,j,n) inc(g[i],mul(str[i][j],s));
}
memcpy(f[x],g,sizeof g);
}
void init() {
str[0][0]=1;
fu(i,1,N) fu(j,1,N) str[i][j]=add(mul(str[i-1][j],j),str[i-1][j-1]);
fu(i,0,N) C[i][0]=1;
fu(i,1,N) fo(j,1,i) C[i][j]=add(C[i-1][j],C[i-1][j-1]);
inv[0]=1;
fu(i,1,N) inv[i]=mul(inv[i-1],i);
inv[N-1]=pow1(inv[N-1],mod-2);
fd(i,N-1,1) {
int t=inv[i-1];
inv[i-1]=mul(inv[i],i);
inv[i]=mul(inv[i],t);
}
}
void Main() {
cin>>n;
init();
fo(i,2,n) {int p; cin>>p; G[p].pb(i);}
cin>>R;
fo(i,1,n) cin>>A[i];
dfs(1);
cout<<f[1][0]<<'\n';
}

浙公网安备 33010602011771号