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;
}
posted @ 2025-04-22 21:04  zxh923  阅读(10)  评论(0)    收藏  举报