专栏文章

题解:AT_abc207_f [ABC207F] Tree Patrolling

AT_abc207_f题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mio2pnfp
此快照首次捕获于
2025/12/02 12:23
3 个月前
此快照最后确认于
2025/12/02 12:23
3 个月前
查看原文
显然树上背包,但是每个点的贡献至多为 11,若该点被控制则相邻点染色时该点无贡献,故而仅使用 dpi,jdp_{i,j} 表示 ii 子树中有 jj 个被控制是不够的,需要多添加一些信息。
定义 dpi,j,0/1/2dp_{i,j,0/1/2} 表示 ii 子树中有 jj 个被控制,00 代表 ii 未染色也未被控制,11 代表 ii 被控制但没被染色,22 表示 ii 染色,不可能出现染色但没被控制的情况,因为染色即控制了本身。
uu 为当前节点,vv 为其中一个儿子,枚举 uu 已遍历子树被控制的个数 iivv 为根的子树被控制点个数 jj,转移方程如下:
  1. uu 未被染色且未被控制,则 vv 不能染色:
dpu,i+j,0=dpu,i,0×(dpv,j,0+dpv,j,1)dp_{u,i+j,0} = dp_{u,i,0} \times (dp_{v,j,0} + dp_{v,j,1})
  1. uu 被控制但不染色,要么 uu 原来没被控制,被 vv 染色后控制,要么 uu 原来就被控制,vv 任意。
dpu,i+j,1=dpu,i1,0×dpv,j,2+dpu,i,1×(dpv,j,0+dpv,j,1+dpv,j,2)dp_{u,i+j,1} = dp_{u,i-1,0} \times dp_{v,j,2} + dp_{u,i,1} \times (dp_{v,j,0} + dp_{v,j,1} + dp_{v,j,2})
  1. uu 染色,vv 要么已被控制,要么没被控制,此时被 uu 控制。
dpu,i+j,2=dpu,i,2×(dpv,j1,0+dpv,j,1+dpv,j,2)dp_{u,i+j,2} = dp_{u,i,2} \times (dp_{v,j-1,0} + dp_{v,j,1} + dp_{v,j,2})
初始化:
显然对于每个点 ii,若不染本身,dpi,0,0=1dp_{i,0,0} = 1
若染本身,dpi,1,2=1dp_{i,1,2} = 1
注意一些细节:
  1. 枚举 i,ji,j 时要倒序枚举,否则会重算。
  2. 计算前要将 dpudp_u 复制到 tt 中,然后 dpudp_u 使用 tt 转移,否则会重算。
  3. dpu,i+j,1dp_{u,i+j,1}dpu,i+j,2dp_{u,i+j,2} 由于 uu 本身被控制所以在 i>0i>0 时才能转移。
  4. dpu,i+j,2dp_{u,i+j,2} 在转移时 j1j-1 可能为负数,所以 只有 j>0j>0 时才能加上 dpu,i,2×dpv,j1,0dp_{u,i,2} \times dp_{v,j-1,0}
  5. 记得取模。

主要代码

CPP
void dfs(int u, int fa){
	sz[u] = 1; 
	dp[u][0][0] = 1, dp[u][1][2] = 1;
	for(int v : e[u]){
		if(v == fa) continue;
		dfs(v, u);
		for(int i = 0; i <= sz[u] + sz[v]; i ++)
			t[i][0] = t[i][1] = t[i][2] = 0;
		for(int i = sz[u]; i >= 0; i --)
			for(int j = sz[v]; j >= 0; j --){
				t[i + j][0] = (t[i + j][0] + dp[u][i][0] * (dp[v][j][0] + dp[v][j][1])) % MOD;
				if(i > 0) t[i + j][1] = (t[i + j][1] + dp[u][i - 1][0] * dp[v][j][2] % MOD + dp[u][i][1] * (dp[v][j][0] + dp[v][j][1] + dp[v][j][2]) % MOD) % MOD;
				if(i > 0) t[i + j][2] = (t[i + j][2] + dp[u][i][2] * ((j > 0 ? dp[v][j - 1][0] : 0) + dp[v][j][1] + dp[v][j][2])) % MOD;
			}
		for(int i = 0; i <= sz[u] + sz[v]; i ++)
			dp[u][i][0] = t[i][0], dp[u][i][1] = t[i][1], dp[u][i][2] = t[i][2];
		sz[u] += sz[v];
	}
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...