1 l r x 修改:a_i \leftarrow \max (a_i, x), \ l \le i \le r;
2 i 撤销:撤销第 i 次操作;
3 i 查询 A_i。
思路
线段树。如果直接做的话,会发现撤销操作极难实现,且区间取 \max 也难以把 tag 应用。
那就不要应用 tag 了。我们可以用一个 set 把所有 tag 存下来,撤销时只需按照修改的方式,递归到节点,直接删除 tag 即可。因为我们需要删除 tag,所以这里的标记不能下传,即所谓的标记永久化技巧。
P6374 「StOI-1」 树上询问
题意
给定 n 个点的树,q 次查询,每次查询一个三元组 (a, b, c),问有多少个点满足,在以这个点为根时,c 是 a, b 的 LCA。
思路
做法很多,这里讲解重剖做法。
分别找到 a, b 方向上离 c 最近的点 A, B,减去其子树大小即可。父亲子树大小为 n - sz_c。
树剖 LCA 写法可以使用如下代码寻找 A, B:
int get(int u, int v) {
if (lca(u, v) != u) return f[u];
else {
if (lca(v, son[u]) == son[u]) return son[u];
else {
for (; f[top[v]] != u; v = f[top[v]]);
return top[v];
}
}
}
这是我做题的时候在讨论区看到的,忘了是哪一位大佬了。
P8366 [LNOI2022] 题
题意
给定长度为 3 n、值域为 [0, 3] 的整数序列 S = s_1 s_2 \cdots s_{3 n}。你需要首先将 S 中的每个 0 替换为 [1, 3] 中的任意一个整数,得到序列 T = t_1 t_2 \cdots t_{3 n},然后给出 n 个长度为 3 的整数序列 {\{ a_{i, 1}, a_{i, 2}, a_{i, 3} \}}_{1 \le i \le n},使得
思路
动态规划。
显然只有排列 213, 132, 321 满足条件。我们将状态设为 dp_{i, a, b, c, d, e, f},六个字母分别表示当前有多少个已匹配的 1, 2, 3, 21, 13, 32,dp 值就表示方案数了。
当 s_i = 0/1 时,转移如下:
dp_{i, a + 1, b, c, d, e, f} \leftarrow dp_{i - 1, a, b, c, d, e, f}
dp_{i, a, b - 1, c, d + 1, e, f} \leftarrow dp_{i - 1, a, b, c, d, e, f} \times b
dp_{i, a, b, c, d, e, f - 1} \leftarrow dp_{i - 1, a, b, c, d, e, f} \times f
当 s_i = 0/2 时,转移如下:
dp_{i, a, b + 1, c, d, e, f} \leftarrow dp_{i - 1, a, b, c, d, e, f}
dp_{i, a, b, c - 1, d, e, f + 1} \leftarrow dp_{i - 1, a, b, c, d, e, f} \times c
dp_{i, a, b, c, d, e - 1, f} \leftarrow dp_{i - 1, a, b, c, d, e, f} \times e
当 s_i = 0/3 时,转移如下:
dp_{i, a, b, c + 1, d, e, f} \leftarrow dp_{i - 1, a, b, c, d, e, f}
dp_{i, a - 1, b, c, d, e + 1, f} \leftarrow dp_{i - 1, a, b, c, d, e, f} \times a
dp_{i, a, b, c, d - 1, e, f} \leftarrow dp_{i - 1, a, b, c, d, e, f} \times d
如何计算贡献?枚举左/右端点(左还是右分类讨论,短区间在左就是左端点,反之同理),那么另一个端点只要满足长度限制就好了。如何解决重复元素问题?我们提前预处理出,对于每个元素,其合法的左/右端点最远能到哪里。具体地,记录每个元素最后出现的位置,枚举到 i 的时候,当前左/右端点就是上一个或者 a_i 的上一次出现位置,哪个更近取哪个。
P2617 Dynamic Rankings
题意
给定长度为 n 的数列 \{ a_n \},m 次操作,每次操作如下:
Q l r k 查询:查询区间 [l, r] 内的第 k 小;
C x y 修改:a_x \leftarrow y。
思路
主席树本质是 n 个前缀和,而要修改的话,就得要修改后缀。那什么数据结构能够维护前/后缀修改单点查询呢?树状数组。