ABC264 题解
B
Problem
有如下 15×15 的矩阵图:

每次询问给定 r 和 c,问该矩阵第 r 行第 c 列是什么颜色。
Scope Limitation
1≤r,c≤15
Solution
这场的 D 题很简单,但是做 B 和 C 却着实废了一番手脚,想了想决定写一下这个 B 的解法,大家通过的方式应该算得上千奇百怪,但这题的 r 和 c 有可能可以出到比较大的地步。
看似十分简单的一道题目,做起来却有些手足无措,大抵原因是并不知道如何最简单的实现。
开始很想手打,但是觉得作为第二题一定会有很简单的规律,虽然事实也正是如此,可我并没能发现,也许直接手打真的会快很多吧。
后来直接写了个八连通扩张,每次扩张一个回字,暴力跑出这个图,显得很蠢。
事实上,真正的规律是这样的,观察 max{|r−8|,|c−8|} 的奇偶性,就能得出答案。
E
Problem
有 n 座城市和 m 个发电站,他们通过 e 条边相连。
如果城市 i 和任意一个发电站在同一个连通块中,我们认为城市 i 通电。
给定 q 次询问,每次询问删掉一条边,影响会持续到下一次询问,问每次删除后,图上有多少座城市通电。
Scope Limitation
1≤n,m<n+m≤2×105,1≤Q≤E≤5×105
Solution
十分套路的题目,存下询问,倒着加边,并查集维护即可。
F
Problem
有一个由 01 组成的 n 行 m 列矩阵,可以花费 ri 的代价将第 i 行的 01 全部翻转,可以花费 ci 的代价将第 j 列的 01 全部翻转。
从 (1,1) 出发,只能向右或下移动,且当前位置与移动目标的颜色必须相同,问最少花费多少代价,才能到达 (n,m)。
Scope Limitation
2≤n,m≤2000
Solution
挺容易想到 dp 的。
设状态 dp[i][j][0/1][0/1] 表示从 (1,1) 走到 (i,j) 且第 i 行与第 j 列是否翻转的最小代价。
一开始没看到只能向右下移动,想了很久,觉得这个状态转移不了,后来手模了一遍样例,才醒悟过来存在这样的限制,那我们的转移就十分简单了。
初始值分别为:
dp[1][1][0][0]=0,dp[1][1][1][0]=r1,dp[1][1][0][1]=c1,dp[1][1][1][1]=r1+c1
转移如下:
- i<n:设根据 x 和 y 算出 (i,j) 的颜色为 a,(i+1,j) 的颜色为 b。
- a=b:dp[i][j][x][y]→dp[i+1][j][0][y]
- a≠b:dp[i][j][x][y]+ri+1→dp[i+1][j][1][y]
- j<m:设根据 x 和 y 算出 (i,j) 的颜色为 a,(i,j+1) 的颜色为 b。
- a=b:dp[i][j][x][y]→dp[i][j+1][x][0]
- a≠b:dp[i][j][x][y]+cj+1→dp[i][j+1][x][1]
状态数 O(n2)
G
Problem
给定 n 个条件,每组条件如下:
Ti 是一个由小写字母组成的长度不超过 3 的字符串,Pi 是一个整数。
定义一个字符串 S 的权值如下:
设 Vi 表示 Ti 在 S 中出现的次数乘上 Pi,则 S 的权值即为 ∑ni=1Vi
求对于给定的 n 个条件,任意由小写字组成的字符串 S 的最大权值,若为正无穷,输出 Infinity
Scope Limitation
1≤N≤18278
Solution
设 P(T) 权值如下:
- 若 T=Ti,P(T)=Pi
- 若 T 不存在任何 Ti 与之相等,则 P(T)=0
设当前 S=s1s2s3……sl,若在末尾加入一个字符 s′,则对权值的影响为 P(s′)+P(sls′)+P(sl−1sls′)。
当然,若 S 的长度小于 2,则权值变化另算,我们也可以在一开始就往 S 中加入两个小写字母以外的字母,根据上述定义,亦能得到正确的值。
于是我们考虑设置这样一张图,图上的每个节点代表一个由两个字母组成的状态,枚举第三个字母,向另一个状态转移连边,例如状态 ab 向状态 bc 连接一条边权为 P(c)+P(bc)+P(abc) 的边。
设 w=26,则我们的点数是 O(w2),边数是 O(w3),由于需要找正环,跑一边 SPFA 最长路,最劣 O(w5),足以通过此题。
Ex
Problem
给定一棵大小为 n 的树,根节点为 1,节点 i(i>2) 的父亲为 Pi。
要求对 k=1,2……n 分别求出对于节点 1 至 k,有多少棵以 1 为根的完美二叉树。
Scope Limitation
1≤n≤3×105,1≤Pi<i
Solution
发现这样一个事实,一定不存在深度大于等于 20 的答案,一棵深度等于 20 的完美二叉树节点的数量为 220−1>3×105,故由此结论。
考虑 dp,设 f[i][j] 表示以节点 i 为根,深度为 j 的完美二叉树的数量,g[i][j] 表示 ∑nk[pk=i]f[k][j]。
那么直接转移即可,每次加入一个点,顺着父亲向根更新。
设当前节点为 v,父节点为 u,以节点 v 为根深度为 cir 的二叉树有 res 棵。
令 val=res×(g[u][cir]−f[v][cir]),简单来说就是减去老的,用新的和另外的子树匹配。
用 res 更新 g[u][cir] 和 f[v][cir],然后 res=val,节点继续向上跳,直到为根。
时间复杂度 O(20n)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步