油尽灯枯之赛
又是美好的爆零日。
我想打球了。
离比赛越近,考得就越烂吗。
老规矩,在前面先写点闲话。
看了 \(\sf yspm\) 的博客“像是人类智慧的结晶”之后,我从 \(\sf imzzy\) 身旁走过时,总想仔细端详一下。
因为他真的很像析出的晶体:或许是小小的一颗,但是很纯。
以及他浑然天成、与生俱来的,似笑非笑的表情,令人回味无穷。
怪不得 \(\sf c9\) 会做那张 \(\rm cqbz\) 和 \(\rm wfls\) 的合照。我理解他了。
\(T1\):给仙人掌的边随机定向,问每个点期望能到达多少点。
感觉是圆方树上恶心换根 \(\tt dp\),写不来。
\(T2\):有向图,进行 \(q\) 次操作:将若干互不相同的边的边权 \(+1\),然后问某个点最短路。
有点降智。一开始以为初始边权全 \(1\),然后发现并不是。
就考虑用势能,将很多边权设为 \(0\) 。然后最短路就不会超过 \(nq\) 。
考虑 \(\tt dijkstra\) 但是用桶排,且在 \(q\) 张图上同时进行。时空复杂度 \(\mathcal O(nq)\) 。
为啥它会快。我以为是整体 \(\tt dp\) 的效果,省去了扫描桶的过程。可能也是吧,但这很蠢……
由于空间会爆,我考虑把 \(q\over 10\) 个操作压一组作询问。每组都要重新求一遍最短路!
没错。也就是说,我一直在维护最短路,然后过一段时间我要重新求一次最短路?
完整说一遍:对单次修改,最短路不超过 \(\mathcal O(n)\),用桶排可做到 \(\mathcal O(n{+}m)\) 维护最短路。然后将新的最短距离作为势能即可。
复杂度 \(\mathcal O(q(n{+}m))\) 其实还蛮无趣的。
\(T3\):求 \(\min\sum_{j=1}^{n-1}\omega(x_j\oplus x_{j+1})\) 其中 \(\omega(n)=\sum_{j\in n}c_j\),需满足 \(x_j\in[l_j,r_j]\) 。保证 \(r_j<2^k\) 。数据范围 \(n,k\leqslant 50\) 。
花了我上午 \(1h\) 左右 \(+\) 整个下午。气死我了 💢
我以为是 \(2^{k/2}\) 之类的。但 \(\textsf{crashed}\) 说:“有没有可能是次数较高的 \(P\) 算法?”
我想,祂其实已经会了。只不过出于知识封锁的习惯,没有说出来。😢
回到题目上。每个数只需选若干 \(\rm highbit\) 使得其满足值域范围,剩下的 \(\rm bit\) 总应该和上一个数保持一致。这些 \(\rm bit\) 是固定的 \(\rm bit\) 的延伸,因此贡献实际出现在固定的 \(\rm bit\) 之间。
更具体地,若 \(x,y\) 有贡献,则 \(x,y\) 之间的固定 \(\rm bit\) 没有 \(x,y\) 多。不难发现这是笛卡尔树。
Comment. 之前需要 \(\mathcal O(2^k)\) 是因为我们在沿着序列方向建笛卡尔树。有时我们要摒弃这种线性的想法。
换成区间 \(\tt dp\),只需记 \(f_{l,i,r,j}\) 为,左端点 \(l\) 选择的数字是 \(i\) 而右端点 \(r\) 选择数字 \(j\) 时,区间内固定 \(\rm bit\) 没有 \(i\) 或 \(j\) 多,最小代价。显然每个位置上的可能数字只有 \(\mathcal O(k)\) 个,即与 \(r_j\) 或 \(l_j\) 的 \(\rm lcp\) 嘛。
枚举 \((l,r)\) 内固定 \(\rm bit\) 最多的位置和它选的数字,复杂度 \(\mathcal O(n^6)\) 。
状态太多,优化之。以 \(h_l\) 指代固定 \(\rm bit\) 的数量。若 \(h_r>h_l\) 则 \(h_r\) 中较高的 \(\rm bit\) 无意义:既不产生贡献,也不带来约束。因此状态中只用记录 \(h\) 较小的那个数。这样至少能 \(\mathcal O(n^5)\) 。
更进一步:转移时只用到 \(f_{l,k,h_k}+f_{k,r,h_k}\),跟 \(h_l\) 也没关系。因此先枚举 \(l,r\) 后,直接枚举 \(k,h_k\) 得到结果 \(g\),再枚举 \(h_l\) 可以直接从 \(g\) 更新。
复杂度 \(\mathcal O(n^4)\) 。由于极其麻烦,我们只能期待 \(\sf Rainybunny\) 给出代码实现了。
如果这篇文章对你有帮助,那么作者是:OneInDark,原文在:https://www.cnblogs.com/OneInDark/p/16599563.html,否则我也不知道这是谁的文章。