8.21 状态设计,DS, Ad-hoc
ZUMA
长度为 \(N\) 的序列,一次消除操作选择一个连续段,长度为 \(K\) 且 \(a_i\) 均相同,将连续段删除并拼接前后两段。求一个长度为 \(N+x\) 的序列 \(b\) 存在某种消除方式将其消除完,而且 \(a\) 是 \(b\) 的子序列,求 \(x\) 的最小值。
\(1 \le N \le 100, 1 \le K \le 5, 1 \le a_i \le 100\)
定义 \(f_{l, r, v, k}\) 表示区间 \(l, r\) 可以删到只剩 \(k\) 个数 \(v\) 的最小代价。于是可以打出 \(\mathcal O(n^3V^2K^2)\) 大暴力。
\(v\) 这一维开销太大了,考虑钦定 \(a_l= v\)。这样做的正确性在于最后要剩 \(k\) 个 \(v\),那么其实 \(l\) 左边的数是独立于右边的数的。考虑反着定义一下,定义给某个区间右边放上 \(k\) 个 \(a_l\),最后删光的最少代价。转移应该还是比较简单的。
T2 放个普及何意味?
[Ynoi Easy Round 2016] 这是我自己的发明
给一个树,\(n\) 个点,有点权,初始根是 \(1\)。
\(m\) 个操作,种类如下:
1 x将树根换为 \(x\)。
2 x y给出两个点 \(x, y\),从 \(x\) 的子树中选每一个点,\(y\) 的子树中选每一个点,求点权相等的情况数。\(1 \le n \le 10^5, 1 \le m \le 5 \times 10^5, 1 \le a_i \le 10^9\)。
换根操作对于子树来说意义不大,钦定一个全局根,对于当前树根 \(r\),如果它在 \(u\) 子树内,则询问时 \(u\) 的子树变成 \([n] \setminus \mathrm{subtree}(u)\),如果 \(u=r\) 则子树变为 \([n]\)。
困难的是第二问,用 dfn 序转化后变为给定 \(l_1, r_1, l_2, r_2\) 求 \(\displaystyle\sum _{x=l_1 }^{r_1}\sum _{y=l_2}^{r_2}[a_x=a_y]\) 。考虑枚举一个 \(v\),使问题变为 \(cnt[a_x=v], cnt[a_y=v]\),差分一下,设 \(g(x, r)=\displaystyle\sum _{i=1}^r [a_i=x]\),则询问转化为:
- \(q_1\):\(\sum _x g(x, r_1) \times g(x, r_2)\)。
- \(q_2\):\(\sum_x g(x, r_1) \times g(x, l_2-1)\)。
- \(q_3\):\(\sum _x g(x, l_1-1) \times g(x, r_2)\)。
- \(q_4\):\(\sum _x g(x, l_1-1) \times g(x, l_2-1)\)。
求 \(q_1+q_4-q_2-q_3\) 的值。莫队的复杂度是 \(\mathcal O(n \sqrt m)\) 的,算一下发现大约在 \(5\times 10^7\) 量级,带 \(4\) 倍常数。然而实际上我们需要将数组倍增一份,所以大概在 \(4 \times 10^8\),卡卡就过了。
考虑到以前的机子很慢,优化一点常数,对于去除子树时的问题:将询问从 \([L, R]\) 改为 \([1, L], (R, n]\),设问题的答案为 \(f(l_1, r_1, l_2, r_2)\),记 \(h(l, r) = f(1, l, 1, r), p(r, r) = f(l, n, 1, r)\),则我们要做:
- Case 1: 一个在扣,\(f(1, l_1, l_2, r_2)+f(r_1+1, n, l_2, r_2)\),变为 \(h(l_1, r_2)-h(l_1, l_2-1)+p(r_1+1, r_2)-p(r_1+1, l_2-1)\),四次询问解决。
- Case 2: 两个都在扣,\(f(1, l_1, 1, l_2)+f(1, l_1, r_2+1, n)+f(r_1+1, n, 1, l_2)+f(r_1+1, n, r_2+1, n)\),容易发现这就是 \(h(l_1, l_2)+p(r_2+1, l_1)+p(r_1+1, l_2)+反正也能搞\)。四次询问解决。
但是现在的机子很快,直接就能过。
[QOJ12121] Golf
构造一个符合以下条件的图:
- 拥有不超过 \(n\) 个点。
- 除了点 \(1\) 和 \(2\) 以外,每个点有且仅有 \(2\) 条出边(允许重边)
- 每个点都能到达 \(1,2\) 之一。
- 从某个点 \(s\) 出发,等概率随机选取出边走,到 \(1,2\) 时停止,最终停在 \(1,2\) 的概率分别为 \(\dfrac{a}{a+b}\) 和 \(\dfrac{b}{a+b}\)。
\(33 \le n \le 100, 1 \le a, b \le 10^9\)
考虑现在我们有两个点,需要 \(a : b\) 的到达比例。数据范围强烈提示折半做。假设 \(a > b\),考虑我们可以通过一步规约到 \(\dfrac{a-b}{2}, b\) 的子问题。和减少了 \(\dfrac{1}{2}\),最后直到有一个数变为 \(0\)。然而并不是每次都能确保 \(\dfrac{a-b}{2}\) 都是整数的,所以这样做只能解决到 \(a+b=2^k\) 的问题。
考虑拓展这个做法。考虑沿用这个每次和减半的想法,凑一个数 \(c\),使 \(a+b+c= 2^k\),则 \(k \le 31\)。
最后把比例为 \(c\) 的返回起点就能消除 \(c\) 的影响。然后考虑如何折半,容易发现 \(k=0\) 时必然存在一个位置为 \(1\) 其余为 \(0\),直接返回 \(1\) 的位置为起点即可;其余情况,\(2^k\) 必然为偶数,则 \(a, b, c\) 中至少有一个偶数。选择不是偶数的那两个做之前的操作,然后对于偶数直接除以 \(2\) 即可。注意卡一下边界,对于 \(1, 1, 0\) 的结尾情况,直接用起点连一下就好了,不需要多开一个。
[QOJ5059] Plants vs Zombies
自己看。
考虑到每只僵尸除了豌豆击打以外没有关系。直接按时间维模拟就完了。复杂度均摊 \(\mathcal O(n \log n)\)。

浙公网安备 33010602011771号