P9746 「KDOI-06-S」合并序列 解题报告
题意:有一个数组,如果一个区间 \([l, r]\) 满足 \(\exists k \in (l, r), a_l \oplus a_r = \oplus a_k\),那么可以将这个区间压缩成一个数 \(\bigoplus_{l \le i \le r} a_i\)。
我们将 \(\bigoplus_{l \le i \le r} a_i\) 记作 \(S(l, r)\)。
\(1\leq T\leq20\),\(1\leq n\leq500\),\(0\leq a_i<512\)。
| 测试点编号 | \(n\) | \(\sum n\leq\) | \(a_i<\) |
|---|---|---|---|
| \(1\) | \(=1\) | \(20\) | \(512\) |
| \(2\) | \(=2\) | \(40\) | \(512\) |
| \(3\) | \(=3\) | \(60\) | \(512\) |
| \(4\) | \(=4\) | \(80\) | \(512\) |
| \(5\) | \(=5\) | \(100\) | \(512\) |
| \(6\sim7\) | \(\leq40\) | \(800\) | \(512\) |
| \(8\sim9\) | \(\leq70\) | \(1~400\) | \(512\) |
| \(10\sim11\) | \(\leq130\) | \(2~600\) | \(512\) |
| \(12\sim13\) | \(\leq300\) | \(6~000\) | \(128\) |
| \(14\sim15\) | \(\leq500\) | \(3~000\) | \(64\) |
| \(16\sim17\) | \(\leq500\) | \(3~000\) | \(128\) |
| \(18\sim20\) | \(\leq500\) | \(10~000\) | \(512\) |
请对程序的常数以及效率给予充分的信任。
似乎特判一下 \(n \le 5\) 的数据,然后总司令可以拿到 \(35\)。
首先就是对 \(n \in [1, 5]\) 进行特判,你可以拿到 \(25\) 分。
然后肯定是区间 DP,考虑设计状态 \(f(l, r)\) 代表 \([l, r]\) 是否能被合并成一个数。

然后,此时的 \(a'[L]\) 和 \(a'[R]\) 都应该是原数组在 \([l, r]\) 上的一段前,后缀。然后 \(a'[K]\) 必然是一段区间 \([u, v]\) 使得 \(x < u \le v < y\)。
也就是说,只要存在一种 \(l \le x < u \le v < y \le r\) 的方案,使得 \(S(l, x) \oplus S(u, v) \oplus S(y, r) = 0\) 且 \(f(l, x)f(u, v)f(y, r) = 1\),那么 \(f(l, r) = 1\)。
你可以暴力枚举 \(x, u, v, y\),这样是 \(\mathcal{O}(n^6)\) 的。可以获得和特判一样的分数。
优化到 \(\mathcal{O}(n^5)\) 是容易的:你只需要枚举 \(u, v, y\),并且在枚举 \(u\) 的同时,将 \([l, u - 1]\) 上的每个前缀和塞到桶里,然后枚举 \(y\) 的时候检查桶中是否有 \(S(u, v) \oplus S(y, r)\) 即可,有 \(35\) 了。
考虑继续优化。显然枚举 \(x, y\),然后判断 \([x + 1, y - 1]\) 内是否有合法区间是很有前途的。因此,我们新增状态 \(g(i, j, k)\) 代表区间 \([i, j]\) 内是否有异或和为 \(k\),且可以被合并的连续子段。
显然对于 \(g(l, r, k)\),我们可以大力枚举 \([l, r]\) 中的每一个区间 \([l', r']\),如果遇到 \(f(l', r') = 1\) 且 \(S(l', r') = k\),那么 \(g(l, r, k) = 1\)。这样的话,\(g\) 数组的复杂度是 \(\mathcal{O}(n^4)\) 的。对于 \(f(l, r)\),我们枚举 \(x, y\),然后如果出现 \(f(l, x)f(y, r)g(x + 1, y - 1, S(l, x) \oplus S(y, r)) = 1\),那么 \(f(l, r) = 1\),这样总复杂度也是 \(\mathcal{O}(n^4)\) 的了。可以拿 \([45, 100]\),如果你对程序效率给予充分信任的话,可能会取到上界。
可不可以再少枚举一个数呢?如果我们只枚举 \(x\),那么就需要维护一个 \(h(j, k)\) 代表最大的 \(u\),使得存在 \(u \le v < y \le r = j\),\(S(u, v) \oplus S(y, r) = k\) 且 \(f(u, v)f(y, r) = 1\)。考虑对 \(h\) 的计算:首先就是算一下 \(z(i, j)\) 代表找到最大的 \(u\) 使得存在 \(u \le v < i\),且 \(f(u, v) = 1\)。计算这个其实是容易的。计算完这个,再扫一遍即可计算 \(h(i, j)\)。再扫一遍即可计算 \(f(l, r)\)。
输出方案时模仿转移,直接找到一种可能的转移就好。总时间 \(\mathcal{O}(n^3)\)。

浙公网安备 33010602011771号