AtCoder agc063_e Child to Parent
首先我们考虑 dp,设出如下几个状态:
-
\(f1_{v,k}\) 表示 \(A_v\) 被 \(k\) 次加上 \(r\) 的操作方案数。
-
\(f2_{v,k}\) 表示 \(A_v\) 总共被加 \(k\) 的操作方案数。
-
\(f3_{v,k}\) 表示 \(A_v=k\) 的操作方案数。
-
\(f4_{v,k}\) 表示 \(A_v\) 减去 \(1\) 一共 \(k\) 次的操作方案数。
这个东西直接做复杂度显然和值域有关,不能通过,但是我们仍然先考虑暴力转移:
-
\(f1_{v}\) 是 \(f4_{w\in son(v)}\) 的卷积。
-
\(f2_{v,r\times k}=f1_{v,k}\)。
-
\(f3_{v,A_v+k}=f2_{v,k}\)。
-
\(f4_{v,k}=\displaystyle\sum_{i\ge k} f3_{v,i}\)。
发现这个东西有卷积,我们考虑多项式。比方说求出 \(f\) 的生成函数 \(F\):
-
\(F_{v,1}(x)=\displaystyle\prod_{w\in son(v)} F_{w,4}(x)\)。
-
\(F_{v,2}(x)=F_{v,1}(x^r)\)。
-
\(F_{v,3}(x)=x^{A_v}\times F_{v,2}(x)\)。
-
\(F_{v,4}(x)=F_{v,3}(x)+\dfrac{F_{v,3}(1)-F_{v,3}(x)}{1-x}\)。
我们详细推导一下最后一个式子,这里为了简单,假设 \(dp\) 数组为 \(f\),\(g\) 为其后缀和,\(F,G\) 分别为其生成函数:
\(\displaystyle G(x)=\sum_{k=0}^{\infty}g_k x^k=\sum_{k=0}^{\infty}(\sum_{i=k}^{\infty}f_i)x_k\)。
交换求和顺序得:
\(\displaystyle G(x)=\sum_{i=0}^{\infty}f_i\sum_{k=0}^{i}x^k=\sum_{i=0}^{\infty}f_i \dfrac{1-x^{i+1}}{1-x}\)。
再进行乘法分配律得:
\(\displaystyle G(x)=\dfrac{1}{1-x}(\sum_{i=0}^{\infty}f_i-\sum_{i=0}^{\infty}f_i x^{i+1})\)。
不难发现,这个东西等价于:
\(\displaystyle G(x)=\dfrac{F(1)-xF(x)}{1-x}=F(x)+\dfrac{F(1)-F(x)}{1-x}\)。
然后就推完了。
但是我们发现这个形式还是不能很快地计算,于是我们考虑设 \(G(x)=F(x+1)\),于是有:
-
\(G_{v,1}(x)=\displaystyle\prod_{w\in son(v)} G_{w,4}(x)\)。
-
\(G_{v,2}(x)=G_{v,1}((1+x)^r-1)\)。
-
\(G_{v,3}(x)=(1+x)^{A_v}\times G_{v,2}(x)\)。
-
\(G_{v,4}(x)=G_{v,3}(x)+\dfrac{G_{v,3}(0)-G_{v,3}(x)}{-x}\)。
显然我们需要求 \(F_{3,1}(1)\),即 \(G_{3,1}(0)\),也就是 \(G_{3,1}(x) \bmod x\),显然我们有:
-
\(G_{v,1}(x) \bmod x^n\) 的值取决于 \(G_{w\in son(v),4}(x) \bmod x^n\) 的值。
-
\(G_{v,2}(x) \bmod x^n\) 的值取决于 \(G_{v,1}(x) \bmod x^n\) 的值。
-
\(G_{v,3}(x) \bmod x^n\) 的值取决于 \(G_{v,2}(x) \bmod x^n\) 的值。
-
\(G_{v,4}(x) \bmod x^n\) 的值取决于 \(G_{v,3}(x) \bmod x^{n+1}\) 的值(因为有除法)。
所以对于一个深度为 \(d\) 的点 \(v\),我们只需要求前 \(d\) 项,也即:
-
\(G_{v,1} \bmod x^{1+d}\)。
-
\(G_{v,2} \bmod x^{1+d}\)。
-
\(G_{v,3} \bmod x^{1+d}\)。
-
\(G_{v,4} \bmod x^{d}\)。
这个东西是能够做到 \(O(n^3)\) 的,于是我们做完了。
这里补充一下代码实现相关的东西:
首先我们上面推出了 \(G_{v,2}(x)=G_{v,1}((1+x)^r-1)\)。
于是我们有 \(\displaystyle G_{v,2}(x)=\sum [x^j] G_{v,1}(x) ((1+x)^r-1)^j\),这里 \([x^j] G_{v,1}(x)\) 表示 \(G_{v,1}(x)\) 中 \(x^j\) 的系数。
然后又发现 \(\displaystyle ((1+x)^r-1)^j=\sum_{k=0}^{j}\binom{j}{k} (-1)^{j-k} (1+x)^{rk}\)。
最后得出 \(\displaystyle [x^m] G_{v,2}(x)=\sum_{j} [x^j] G_{v,1}(x) \sum_{k=0}^{j} \binom{j}{k} (-1)^{j-k} [x^m] (1+x)^{rk}\),不难发现 \([x^m] (1+x)^{rk}=\binom{rk}{m}\),代入进去即可。
这个就是下面 \(f,g\) 干的事情,计算出 \(G_{v,2}(x)\) 的系数。
然后因为我们有 \(G_{v,3}(x)=(1+x)^{A_i} G_{v,2}(x)\),且 \(\displaystyle (1+x)^{A_i}=\sum_{j=0}^{A_i}\binom{A_i}{j} x^j\)。
所以 \([x^j] (1+x)^{A_i}=\binom{A_i}{j}\),把这个东西和 \(g\) 卷积起来就得到了 \(G_{v,3}\) 的系数。
因为 \(G_{v,4}(x)=G_{v,3}(x)+\dfrac{G_{v,3}(0)-G_{v,3}(x)}{-x}\),这个东西其实就是 \(\displaystyle\sum_{j=0}^{\infty}a_jx^j+\sum_{j=1}^{\infty}a_{j+1}x^j\),即 \(\displaystyle\sum_{j=0}^{\infty}[x^j]+[x^{j+1}]\)。
所以 \(dp\) 数组从 \(h_j+h_{j+1}\) 转移。
因为 \(dp\) 数组代表该节点做了 \(j\) 次操作的方案数,而根节点不能操作,所以答案为 \(dp_{1,0}\)。
AC code:
#include<bits/stdc++.h>
#define int long long
#define N 305
#define pii pair<int,int>
#define x first
#define y second
#define mod 998244353
#define inf 2e18
using namespace std;
int T=1,n,r,fa[N],f[N],g[N],h[N],a[N],dep[N],inv[N];
int c[N][N],rc[N][N],dp[N][N];
int ksm(int x,int y){
int res=1;
while(y){
if(y&1)(res*=x)%=mod;
(x*=x)%=mod;
y>>=1;
}
return res;
}
void init(){
int x=1;
inv[0]=1;
for(int i=1;i<N;i++){
(x*=i)%=mod;
inv[i]=ksm(x,mod-2);
}
for(int i=0;i<N;i++){
for(int j=0;j<=i;j++){
if(!j)c[i][j]=1;
else c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
}
}
int C(int n,int m){
if(n<m||n<0||m<0)return 0;
int res=inv[m];
for(int i=1;i<=m;i++){
(res*=(n-i+1)%mod)%=mod;
}
return res;
}
void init2(){
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
rc[i][j]=C(r*i,j);
}
}
}
void solve(int cs){
init();
cin>>n;
for(int i=2;i<=n;i++){
cin>>fa[i];
dep[i]=dep[fa[i]]+1;
}
cin>>r;
for(int i=1;i<=n;i++){
cin>>a[i];
dp[i][0]=1;
}
init2();
for(int i=n;i>1;i--){
memset(f,0,sizeof f);
memset(g,0,sizeof g);
memset(h,0,sizeof h);
for(int j=0;j<=dep[i];j++){
for(int k=0;k<=j;k++){
if(j%2!=k%2)(f[k]+=dp[i][j]*(mod-c[j][k])%mod)%=mod;
else (f[k]+=dp[i][j]*c[j][k]%mod)%=mod;
}
}
for(int j=0;j<=dep[i];j++){
for(int k=0;k<=dep[i];k++){
(g[k]+=f[j]*rc[j][k])%=mod;
}
}
for(int j=0;j<=dep[i];j++){
f[j]=C(a[i],j);
}
for(int j=0;j<=dep[i];j++){
for(int k=0;k<=j;k++){
(h[j]+=f[k]*g[j-k])%=mod;
}
}
for(int j=0;j<dep[i];j++){
dp[i][j]=(h[j]+h[j+1])%mod;
}
dp[i][dep[i]]=0;
memset(h,0,sizeof h);
for(int j=0;j<dep[i];j++){
for(int k=0;k<=j;k++){
(h[j]+=dp[i][k]*dp[fa[i]][j-k]%mod)%=mod;
}
}
memcpy(dp[fa[i]],h,sizeof h);
}
cout<<dp[1][0]<<'\n';
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// cin>>T;
// init();
for(int cs=1;cs<=T;cs++){
solve(cs);
}
return 0;
}