sol

设状态 \(dp_{i,j}\) 表示考虑到节点 \(i\),包括了 \(i\) 这个节点的连通块的权值和(只考虑子树内的)余数为 \(j\) 的方案数。

下文所说的“连通块的和”指连通块内的权值和对 \(3\) 取模后的值。

转移如下:


void dfs(int x,int fa){
	dp[x][a[x]%3]=1;
	for(int i:e[x])
		if(i!=fa){
			dfs(i)
			int dpx0=dp[x][0];
			int dpx1=dp[x][1];
			int dpx2=dp[x][2];
			//用 dp[x][0] 举例,dp[i][0]*dpx0 表示某一个子节点所在的连通块和为 0,然后和包含了 x 的连通块拼起来的方案数,即不断这条边的方案数。dp[i][1]*dpx0 表示断掉这条边。
			dp[x][0]=dp[i][0]*dpx0+dp[i][1]*dpx2+dp[i][2]*dpx1+dp[i][1]*dpx0;
			dp[x][1]=dp[i][0]*dpx1+dp[i][1]*dpx0+dp[i][2]*dpx2+dp[i][1]*dpx1;
			dp[x][2]=dp[i][0]*dpx2+dp[i][1]*dpx1+dp[i][2]*dpx0+dp[i][1]*dpx2;
		}
}
posted @ 2025-07-25 11:01  立花廿七  阅读(16)  评论(0)    收藏  举报