CF 紫色典题

5E Bindian Signalizing

给定一个长度为 \(n\) 的环 \(a\),求有多少对 \(i \ne j\) 满足 \(i, j\) 形成的两段弧上,至少有一段弧上不包含比 \(\min(a_i, a_j)\) 大的点。

\(3 \le n \le 10^6\)\(1 \le a_i \le 10^9\)


不妨将第最大的数放在第一个位置断环为链。

此时对于 \(a_2 \sim a_n\),最优的匹配方法必然不会越过 \(a_1\),直接套路单调栈维护一个递减序列即可。

然后直接正、反各扫一遍求出 \(a_1\) 能和哪些匹配。

时间复杂度 \(O(n)\)

24D Broken robot

有一张 \(n \times m\) 的网格图,初始机器人在 \((i, j)\)

每一步机器人可能往左、右、下之一移动一格,或者停留在本地。

机器人在不离开棋盘的前提下等概率选取每一步的方案,求期望多少步走到第 \(n\) 行。

保留 \(4\) 位小数。

\(1 \le n, m \le 10^3\)


\(f(i, j)\) 表示从 \((i, j)\) 开始的答案。

\[f(x, y) = 1 + (f(x, y) + f(x, y + 1) + f(x, y - 1) + f(x + 1, y)) / 4 \]

类似可以列出 \((n-1)m\) 个方程,直接高斯消元可以做到 \(O(n^6)\) 的复杂度。

考虑到上面的不会影响下面的,于是对每一行依次进行高斯消元,总共 \(O(n)\) 轮,每轮只有 \(O(n)\) 个未知量,可以做到 \(O(n^4)\) 的复杂度。

这时发现系数矩阵其实是一个稀疏矩阵,很多位置是 \(0\),是没有必要进行消除的,也就是说直接手动消元即可做到 \(O(n)\) 消单轮。

总时间复杂度 \(O(n^2)\)

55D Beautiful numbers

一个正整数 \(x\) 是美丽的当且仅当对于其每一个非零位上的 \(y\),都有 \(y\mid x\)

\(t\) 组数据,求 \([l, r]\) 有多少数是美丽的。

\(1 \le t \le 10\)\(1 \le l \le r \le 9 \cdot 10^{18}\)


\({\rm lcm}(1, 2, \cdots, 9) = 2520\),故 \(x \bmod y = (x \bmod 2520) \bmod y\)

由此可以考虑记录当前数位的 \({\rm lcm}\)\(x \bmod 2520\),进行数位 dp。

这样做的时间复杂度看上去是 \(O(t \log w \cdot 2520^2 \cdot \log 2520)\),但其实可以进行一些常数的优化。

例如 \(\rm lcm\) 的有效数目其实不多,可以使用记忆化搜索仅保留有效状态,或者直接预处理出可能的 \(\rm lcm\),以及中途求现有数位的 \(\rm lcm\) 的过程可以直接预处理查表,而非现求。

148D Bag of mice

袋子里有 \(w\) 只白鼠和 \(b\) 只黑鼠 ,A 和 B 轮流从袋子里抓,谁先抓到白色谁就赢。

A 每次随机抓一只,B 每次随机抓完一只之后会有另一只随机老鼠自己跑出来。

如果两个人都没有抓到白色则 B 赢。A 先抓,求 A 赢的概率,要求绝对误差或者相对误差不超过 \(10^{-9}\)

\(0 \le w, b \le 1000\)


直接用 \(f(w, b)\) 表示答案。

分为以下 4 种情况分别 dp 下去即可:

  • 先手白
  • 先手黑,后手白
  • 先手黑,后手黑,跑白
  • 先手黑,后手黑,跑黑

时间复杂度 \(O(n^2)\)

242E XOR on Segment

给定 \(n\) 个数的序列 \(a\)\(m\) 次操作,操作有两种:

  1. \(\sum_{i=l}^r a_i\)

  2. \(a_l\sim a_r\) 异或上 \(x\)

\(1\le n\le 10^5\)\(1\le m\le 5\times 10^4\)\(0\le a_i\le 10^6\)\(1\le x\le 10^6\)


拆位,对每一位分别建一棵线段树,只需要支持区间取反,区间求和即可。

时间复杂度 \(O(n \log x \log n)\),听说直接暴力循环展开也挺快。

246E Blood Cousins Return

给定一片包含 \(n\) 个点的森林,每棵树的根都给定,每个结点处有一个字符串。

\(m\) 次询问,每次给定 \(v, k\),求 \(v\) 的所有 \(k\) 级儿子中有多少个不同的字符串。

\(1 \le n, m \le 10^5\)


先考虑如果只是求 \(k\) 级儿子的个数怎么做。

预处理出 dfs 序,对每一个深度都开一个 vector 将点按照 dfs 序存进去,查询的时候直接二分出对应的区间即可。

想到这一步,本题做法就几乎显然了:相当于是进行静态区间数颜色!

把询问离线下来搞个树状数组即可。

时间复杂度 \(O(n \log n)\)

311B Cats Transport

\(n\) 个站台,第 \(i - 1\)\(i\) 站台之间的距离为 \(d_i\)

\(m\) 名乘客,第 \(i\) 名在 \(t_i\) 时刻出现在第 \(h_i\) 站台。

\(p\) 辆车,每辆车从 \(1 \to n\) 不停留驶过每个站台并立刻带上所有站台边的乘客。

合理安排 \(p\) 辆车分别的发车时间(可以为负数),最小化所有乘客的总等待时间。

\(2 \le n \le 10^5\)\(1 \le m \le 10^5\)\(1 \le p \le 100\)\(0 \le t_i \le 10^9\)\(1 \le d_i < 10^4\)


首先很容易发现可以把所有的乘客等效地移动到第 \(1\) 号站台(需要重新修改出现时间 \(t\)),也就是说,原问题很容易等价到一个 \(n=1\) 的问题。

将新的 \(t\) 数组排序并求前缀和 \(S\)

\(f(i, j)\) 表示已经接到了前 \(i\) 个人,发出了 \(j\) 辆车,最小等待时间。

\[f(i, j) = \min_{k < i} \{ f(k, j-1) + (j - k)t_j - (s_j - s_k) \} \\ \]

化开这个式子:

\[f(i, j) = f(k, j-1) + j \cdot t_j - k \cdot t_j - s_j + s_k \\ f(i, j) + s_j - j \cdot t_j = - t_j \cdot k + [f(k, j - 1) + s_k] \\ \]

\(j-1\) 层的决策看作若干个点 \((k, f(k,j-1) + s_k)\),转移即是用一条斜率为 \(-t_j\) 的直线去截凸包,得到最小的截距。

考虑到 \(-t_j\) 是单调的,单调队列维护下凸壳即可。

时间复杂度 \(O(mp)\)

372C Watching Fireworks is Fun

\(n\) 个区域,相邻区域之间距离为 \(1\)

\(m\) 次烟花表演,第 \(i\) 次在 \(a_i\) 处燃放,时刻为 \(t_i\),如果你此时在 \(x\) 位置,则你的愉悦值会增加 \(b_i - |a_i - x|\)

每个单位时间你可以移动不超过 \(d\) 个单位距离,并且初始位置可以任选,最大化愉悦值。

\(1 \le n \le 150000\)\(1 \le m \le 300\)\(1 \le b_i, t_i \le 10^9\)\(t_i \le t_{i + 1}\)


\(f(i, j)\) 表示第 \(t_i\) 时刻位于 \(j\) 的最优答案。

转移为 \(f(i, j) = \max_{k} \{f(i-1,k) + value(i, j)\}\),其中 \(|k - j| \le (t_i - t_{i - 1}) \times d\)

发现当 \(j\) 单调递增的时候,\(k\) 的合法取值是一个滑动窗口,单调队列维护一下最值即可。

时间复杂度 \(O(nm)\)

375D Tree and Queries

给定一棵 \(n\) 个节点的树,根节点为 \(1\)。每个节点上有一个颜色 \(c_i\)

\(m\) 次询问 u k,求在以 \(u\) 为根的子树中,出现次数 \(\ge k\) 的颜色有多少种。

\(2\le n\le 10^5\)\(1\le m\le 10^5\)\(1\le c_i,k\le 10^5\)


考虑 dsu on tree。

维护两个全局数组,\(cnt_i\) 表示当前颜色 \(i\) 出现了多少次,\(res_i\) 表示当前有多少颜色出现了 \(\ge i\) 次。

思考加入一个点 \(c_u\) 之后这两个数组会怎么变:\(cnt_{c_u}\) 会增加 \(1\),然后 \(res_{cnt_{c_u}}\) 会增加 \(1\)

删除一个点也是完全同理的,于是离线后便可以做到 \(O(n \log n)\)

CF451E Devu and Flowers

\(n\) 种物品,第 \(i\) 种物品有 \(f_i\) 个,求选出 \(m\) 个物品的方案数,对 \(10^9+7\) 取模。

\(1 \le n \le 20\)\(0 \le f_i \le 10^{12}\)\(0 \le m \le 10^{14}\)


经典可重集组合数。

先考虑 \(m \le \min f\) 的时候,答案是多少。这时显然等价于任何物品都有无限个,可以使用插板法,得到答案为 \(\binom{n+m-1}{n-1}\)

接下来使用容斥原理,考虑用 \(\binom{n+m-1}{n-1}\) 这个“所有物品都有无限个”的总量去减去不合法的方案数数量。

枚举 \(S\),强制令 \(S\) 中的物品的选取数额都是不合法的(超限),而其他物品不管选取数额合不合法。

在这个限制下,相当于是先把 \(\forall u \in S\) 都选取 \(f_u + 1\) 个,在此基础上再做正常的组合数,也就是说,方案数为:

\[\binom{n+m-1-\sum_{u \in S} (f_u + 1)}{n-1} \]

最后一个问题是如何快速计算这个组合数,考虑到下指标很小,可以使用 \(\binom{x}{y} = \frac{x^{\underline{y}}}{y!}\) 来计算组合数。

时间复杂度 \(O(n2^n)\)

CF468C Hack it!

\(f(x)\)\(x\) 的十进制各个数位之和。

给定 \(a\),构造 \(l, r\),使得 \(1 \le l \le r \le 10^{200}\),并且:

\[\sum_{i=l}^{r} f(i)\equiv 0 \pmod a \]

\(1 \le a \le 10^{18}\)


考虑到 \(f(10^{18} + x) = f(x) + 1\)

那么,设 \(f(1)+\cdots+f(10^{18}) \bmod a\)\(x\),我们可以通过不断将首项 \(f(i)\) 替换为 \(f(10^{18} + i)\)(区间右移一个单位)使得 \(x\) 增加 \(1\)

所以现在求出 \(x\) 即可。

尝试求 \(\sum_{i=0}^{10^{18}-1}f(i)\),总共 \(10^{18}\) 个数,\(18\) 个数位,每个数位出现 \(0\sim 9\) 的次数都是相等的,为 \(10^{17}\) 次。

那么总共数码和为 \(45 \times 10^{17} \times 18 = 81 \times 10^{18}\)

时间复杂度 \(O(1)\)

CF487E Tourists

给定一张 \(n\) 个点 \(m\) 条边的无向图,点带权 \(w_i\)

\(q\) 次操作,分为两种:

  • C a w:将 \(a\) 的权值重新赋值为 \(w\)

  • A a b:挑选一条从 \(a \to b\) 的简单路径(每个点至多经过一次),最小化路径上的最小点权。

\(1 \le n, m, q \le 10^5\)\(1 \le w_i \le 10^9\)


先建出广义圆方树,方点的权值设置为其所在点双的 \(\min w\)

询问的答案显然就是圆方树上圆点 \(a, b\) 之间路径的权值的最小值。

考虑修改,一个直接的想法是 \(a\) 对应的圆点直接更新,对每一个方点维护一个 multiset,暴力更新所有涉及到 \(a\) 的方点。

但这样的复杂度是错的,比如有一棵菊花图,那么权值被修改的方点个数可以达到 \(O(n)\) 级别。

考虑改造方点的定义,在圆方树被定了根的前提下,方点的权值设置为其所有儿子的 \(\min w\)

这样一次修改 \(w_a\) 只会造成至多一个方点的权值修改。

值得注意的是,在这种转化下,如果查询的路径 \(a, b\) 的 LCA 是一个方点的话,就需要单独考虑一下 LCA 的父亲的 \(w\)

于是将圆方树树链剖分即可维护。

时间复杂度 \(O(n\log^2 n)\)

CF519E A and B and Lecture Rooms

给定一棵 \(n\) 个点的树,\(m\) 次询问 \(u, v\),求到 \(u, v\) 距离相等的点的个数。

\(1 \le n, m \le 10^5\)


\(u, v\) 中点为 \(w\),那么以 \(w\) 为根时,\(w\) 的直系儿子分别为一棵子树的根,答案即为 \(n\) 减去 \(u\) 所在的子树的大小 和 \(v\) 所在的子树的大小。

于是直接给树固定根,通过 LCA 求出 \(u, v\) 的中点,分类讨论一下:

  • 如果中点就是 LCA,那么答案为 \(n-\) LCA 的包含 \(u\) 的子树大小 \(-\) LCA 的包含 \(v\) 的子树大小。

  • 如果中点不是 LCA,那么答案为 LCA 的子树大小 \(-\) LCA 的包含 \(u, v\) 中较深一者的子树大小。

时间复杂度 \(O(n \log n)\)

CF570D Tree Requests

给定一棵 \(n\) 个结点的树,\(1\) 是根,\(i\) 的父亲是 \(p_i\),每个结点上有一个小写字母。

\(m\) 次询问 \(v, h\),求 \(v\) 的子树中深度为 \(h\) 的结点能否任意排成一个回文串。

\(1 \le n, m \le 5 \times 10^5\)


26 个英文字母的奇偶性可以压缩到一个 int 里表示。

离线做法的话,dsu on tree 显然是可以 \(O(n \log n)\) 的;或者把每一个询问差分为 dfs 序上该层的一段,然后直接 dfs 一遍,维护全局数组作差,是可以 \(O(n)\) 的。

在线做法的话,每层结点存到一个 vector 里,并预处理异或前缀和,询问时二分出该层对应的 vector 的子树内的区间即可。时间复杂度 \(O(n \log n)\)

CF600E Lomsat gelral

有一棵 \(n\) 个结点的以 \(1\) 号结点为根的有根树,\(i\) 号结点的颜色为 \(c_i\)

如果一种颜色在以 \(x\) 为根的子树内出现次数最多,称其在以 \(x\) 为根的子树中占主导地位。显然,同一子树中可能有多种颜色占主导地位。

对于每一个 \(i\in[1,n]\),求出以 \(i\) 为根的子树中,占主导地位的颜色的编号和。

\(1 \le n\le 10^5\)\(1 \le c_i\le n\)


Dsu on tree \(O(n \log n)\)

CF609E Minimum spanning tree for each edge

给定一张 \(n\) 个点 \(m\) 条边的带权无向图,对于每条边求出必须包含这条边的最小生成树的权值。

\(1 \le n \le 2 \cdot 10^5\)\(n-1 \le m \le 2 \cdot 10^5\)\(1 \le w_i \le 10^9\)


直接先求一遍最小生成树。

如果边 \(i\) 在最小生成树上,那么它对应的答案就是最小生成树的权值。

如果 \(i\) 不在最小生成树上,考虑它加入到最小生成树上时增加的环,通过倍增的方式找到这个环上边权最大的边,将其断掉即可。

时间复杂度 \(O(m \log m)\)

CF613D Kingdom and its Cities

给定一棵 \(n\) 个结点的树,\(q\) 次询问,每次给定 \(k_i\) 个点 \(u_1, u_2, \cdots, u_{k_i}\),求至少要删除树上多少个点,才能使得这 \(k_i\) 个点两两不连通。如果无解输出 \(-1\)

注意 \(\forall u_i\) 都是不能被删除的。

\(1 \le n, q \le 10^5\)\(q \le \sum k_i \le 10^5\)


看到 \(\sum\) 想到虚树。

现在问题转化为仅有一次询问。如果有两个被标记点是相邻的那么就必然无解,否则必然有解。

自上而下考虑,如果一个点是被标记的,那么它的所有内含标记点的儿子都必须被删除。

如果一个点是没有标记的,但它是有两个及以上内含标记点的儿子,则它本身必须被删除;否则完全可以推迟删除。

时间复杂度 \(O(n \log n)\)

CF617E XOR and Favorite Number

给定一个长度为 \(n\) 的序列 \(a\),再给一个数字 \(k\)

给出 \(m\) 组询问,每组询问给出一个区间 \(l_i, r_i\),求这个区间里面有多少个子区间的异或和为 \(k\)

\(1 \le n,m \le 10^5\)\(0 \le k,a_i \le 10^6\)\(1 \le l_i \le r_i \le n\)


子区间异或和可以转化为前缀异或和的两个端点的异或值。

想到莫队,开个桶随便跑一下就可以了。

时间复杂度 \(O(n \sqrt{n})\)

CF620E New Year Tree

给出一棵 \(n\) 个节点的树,根节点为 \(1\)。每个节点上有一种颜色 \(c_i\)\(m\) 次操作。操作有两种:

  1. 1 u c:将以 \(u\) 为根的子树上的所有节点的颜色改为 \(c\)

  2. 2 u:询问以 \(u\) 为根的子树上的所有节点的颜色数量。

\(1\le n,m\le 4\times 10^5\)\(1\le c_i,c\le 60\)


先求一遍 dfs 序。看到 \(c \le 60\),想到可以用一个 long long 把“区间中是否含有颜色 \(i\)”压位。

于是只要写一个线段树支持区间赋值,查询区间或和即可。

时间复杂度 \(O(n \log n)\)

CF622F The Sum of the k-th Powers

\(\sum_{i=1}^{n} i^k \bmod (10^9 + 7)\)

\(1 \le n \le 10^9\)\(1 \le k \le 10^6\)


\(k\) 次自然数幂和是一个 \(k+1\) 次多项式,所以暴力求出 \(f(1), \cdots, f(k + 1)\) 然后拉格朗日插值即可。

时间复杂度 \(O(k)\)

CF713C Sonya and Problem Wihtout a Legend

给定一个有 \(n\) 个正整数的数组,一次操作中,可以把任意一个元素 \(+1\)\(-1\)。(元素可被减至负数或 \(0\)),求使得原序列严格递增的求最小操作次数。

*(加强)P4597:\(1 \le n \le 5\times 10^5\)\(1 \le a_i \le 10^9\)


严格递增可以通过将初始时 \(a_i - i\) 转化为不下降。

使用堆来维护这个过程,考虑末尾加入一个 \(x\) 时,记 \(y\) 为加入 \(x\) 后堆中最大值:

如果 \(x = y\),说明加入这个数依然是不下降的,答案不变。

如果 \(x < y\),那么我们强行把 \(y\) 先降到 \(x\),修改堆中 \(y\) 元素的值为 \(x\)\(ans \gets ans + (y - x)\),然后继续后续过程即可。

考虑这个做法的正确性,一个疑问是,如果 \(y\) 降到 \(x\) 之后,序列不再不下降了怎么办?

不妨设序列的不下降被打破是因为 \(z > x\),且 \(z\) 出现在 \(y\) 之前。如果后续数字把 \(z\) 本身给压下来了,那固然更好。否则我们只需要在考虑完所有数后,把当时的“\(y\) 压到 \(x\)”修改为“\(y\) 压到 \(z\)\(x\) 升到 \(z\)”,不难发现这会使得矛盾消除,且答案还是不变的。

当然 \(z\) 可能不止一个,在这种情况下,取最大的 \(z\) 即可。

时间复杂度 \(O(n \log n)\)

当然,通过这个过程,我们也可以知道,最终序列中出现的数,固然只会是原来就存在的数。

CF734E Anton and Tree

给一棵 \(n\) 个节点的树,每个点为黑色或白色,一次操作可以使一个相同颜色的连通块变成另一种颜色,求使整棵树变成一种颜色的最少操作数。

\(1 \le n \le 2 \times 10^5\)


同色相邻缩点,得到一棵新的树,相邻点颜色不同。

令这棵树的直径长度为 \(d\),显然需要 \(\lfloor\frac{d}{2}\rfloor\) 次操作,不断修改直径中点的颜色即可。

时间复杂度 \(O(n)\)

CF739E Gosha is hunting

现在一共有 \(n\) 只神奇宝贝。 你有 \(a\) 个 X 和 \(b\) 个 Y。X 抓到第 \(i\) 只神奇宝贝的概率是 \(p_i\),Y 抓到的概率则是 \(q_i\)。不能往同一只神奇宝贝上使用超过一个同种的 X / Y,但是可以往同一只上既使用 X 又使用 Y(都抓到算一个)。请合理分配每个球抓谁,使得你抓到神奇宝贝的总个数期望最大,并输出这个值。

误差不超过 \(10^{-4}\)

\(2 \le n \le 2000\)\(0 \le a, b \le n\)\(0\le p_i, q_i \le 1\)


wqs 二分。

显然的 dp 是 \(f(i, x, y)\) 表示前 \(i\) 个用了 \(x\) 个 X,\(y\) 个 Y,最大的收益。这样是 \(O(n^3)\) 的。

注意到假如取消 Y 只能选择至多 \(b\) 个的限制,可以无限的选,那么这个 dp 显然可以做到 \(O(n^2)\)

给 Y 的选择赋予一个代价 \(cosb\),每在 Y 的上限无限的情况下,每选择一个 Y 最终答案就要扣除 \(cosb\)。我们可以通过二分 \(cosb\) 的方法使得最终恰好选择了 \(b\) 个 Y。

于是便可以做到 \(O(n^2 \log n)\) 了。其实如法炮制一下,也二分一个 \(cosa\),用同样的方法来处理 X,则可以将时间复杂度做到 \(O(n \log^2 n)\)

CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

一棵 \(n\) 个结点的根为 \(1\) 的树,每条边上有一个小写英文字母。

一条简单路径被称为好的当且仅当路径上的字符经过重新排序后可以变成一个回文串。

求每个子树中最长的好的路径的长度。

\(1 \le n \le 5 \cdot 10^5\)\(|\Sigma| \le 22\),即 a \(\sim\) v


将字母的奇偶性压位,记 \(dis_u\) 表示 \(1 \to u\) 路径的异或和。

一条路径 \(u, v\) 的异或值为 \(w = dis_u \oplus dis_v\),一条路径是好的当且仅当 \({\rm popcount}(w) \le 1\)

考虑 dsu on tree,\(u\) 为根的子树的答案首先对 \(u\) 的 所有儿子 \(v\) 的答案取 \(\max\),然后只考虑经过 \(u\) 的路径。

那么,对 \(dis\) 开桶,\(val_w\) 表示 \(dis_v = w\)\(dep_v\) 的最大值。

保留 \({\rm maxson}(u)\) 的子树内的所有信息,然后依次遍历每一棵其他子树,用 \(dep_x + val_{y} - 2 dep_u\) 更新答案即可,其中 \({\rm popcount}(y \oplus dis_x) \le 1\)。遍历完一棵子树后,再用它去更新 \(val\)

时间复杂度 \(O(|\Sigma| n \log n)\)

CF786B Legacy

线段树优化建图。

CF817F MEX Queries

维护一个集合,初始为空。

有 3 种操作:

  1. \([l,r]\) 中在集合中没有出现过的数添加到集合中。

  2. \([l,r]\) 中在集合中出现过的数从集合中删掉。

  3. \([l,r]\) 中在集合中没有出现过的数添加到集合中,并把 \([l,r]\) 中在集合中出现过的数从集合中删掉。

每次操作后输出集合的 \(\operatorname{mex}\)

\(1\le n\le 10^5\)\(1\le l\le r\le 10^{18}\)


离散化之后就变成了:

  1. 区间赋值 \(0/1\)

  2. 区间取反。

  3. 查询最小的 \(0\) 的位置。

于是简单维护区间和线段树二分回答询问即可。

时间复杂度 \(O(n \log n)\)

CF833B The Bakery

将一个长度为 \(n\) 的序列 \(a\) 分为 \(k\) 段,使得总价值最大。

一段区间的价值表示为区间内不同数字的个数。

\(1 \le a_i \le n\leq 35000\)\(1 \le k \leq \min(50, n)\)


暴力 dp \(f(i, k) = \max \{ f(j - 1, k - 1) + val(j, i) \}\)

考虑用线段树维护所有的决策,当末尾新增加了一个数后,相当于是将 \(last_v, i\) 之间的决策区间 \(+1\),然后直接维护全局最大值即可。

时间复杂度 \(O(nk \log n)\)

CF868F Yet Another Minimization Problem

给定一个序列 \(a\),要把它分成 \(k\) 个子段。每个子段的费用是其中相同元素的对数。求所有子段的费用之和的最小值。

\(2 \le n \le 10^5\)\(2 \le k \le \min(n, 20)\)\(1 \le a_i \le n\)


暴力式子 \(f(i, j) = \min \{ f(k-1, j - 1) + w(k, i) \}\)

考虑一个事实,当 \(f(\cdots, k-1)\) 都已经知道时,\(f(i, k)\) 的最优决策点是随着 \(i\) 上升而不降的。

为什么呢?考虑 \(f(i-1, k)\) 的所有决策的价值如何转化为 \(f(i, k)\) 的决策的价值,实际上是经过了若干个前缀加,所以靠前的决策肯定会变劣。

所以进行决策单调性分治即可。在过程中需要求 \(w\) 时,直接使用类似莫队的增删方法即可,均摊是 \(O(1)\) 的。

时间复杂度 \(O(nk \log n)\)

CF888G Xor-MST

给定 \(n\) 个结点的无向完全图。每个点有一个点权为 \(a_i\)。连接 \(i\) 号结点和 \(j\) 号结点的边的边权为 \(a_i\oplus a_j\)

求这个图的 MST 的权值。

\(1\le n\le 2\times 10^5\)\(0\le a_i< 2^{30}\)


对每个连通块维护一棵 trie,然后维护一棵全局 trie,通过将两棵 trie 做差就可以得到去除某一个连通块的 trie 树。

于是直接套用 boruvka 即可做到 \(O(n \log^2 n)\)

另外的巧妙解法是直接建出全局 trie,然后对于每一个 trie 上有两个儿子的结点,都需要建一条边把其两个儿子连通在一起。直接暴力遍历子树中的所有点对即可做到 \(O(n \log^2 n)\)

CF896C Willem, Chtholly and Seniorious

珂朵莉树。

CF906D Power Tower

给定一个数列 \(w_1,w_2,...,w_n\) 和模数 \(m\)\(q\) 次询问某一个区间 \([l,r]\),求 \(w_l^{w_{l+1}^{{\cdots}^{w_r}}} \bmod m\) 的值。

\(1 \le n, q \le 10^5\)\(1 \le w_i, m \le 10^9\)


扩展欧拉定理:

\[a^p \equiv a^{p \bmod \varphi(m) +\varphi(m)} \qquad p \ge \varphi(m) \]

于是考虑将 \(r\) 左移以使得区间任何一个数都 \(>1\)。不断套用扩展欧拉定理,模数在 \(O(\log w)\) 次之后就会变成 \(1\),这时直接终止计算即可。

时间复杂度 \(O(q \log^2 n)\)

CF920F SUM and REPLACE

给定 \(n\) 个数的数组 \(a\)\(m\) 次操作。操作有两种:

  1. \(i\in[l,r]\) 中的所有 \(a_i\) 替换为 \(d(a_i)\)\(d(x)\) 表示 \(x\) 的正约数的个数。

  2. \(\sum_{i=l}^r a_i\)

\(1\le n,m\le 3\times 10^5\)\(1\le a_i\le 10^6\)


一个数被替换 \(O(\log \log a)\) 次之后就会变成 \(1\) 或者 \(2\),之后一直不变。

故维护一下区间是不是全为 \(1/ 2\),若是直接返回,否则暴力递归修改即可。

均摊时间复杂度 \(O(m \log n)\)

CF1039D You Are Given a Tree

有一棵 \(n\) 个节点的树。

其中一个简单路径的集合被称为 \(k\) 合法当且仅当:

树的每个节点至多属于其中一条路径,且每条路径恰好包含 \(k\) 个点。

对于 \(k\in [1,n]\),求出 \(k\) 合法路径集合的最多路径数
即:设 \(k\) 合法路径集合为 \(S\),求最大的 \(|S|\)

\(1 \le n \leq 10^5\)


容易发现答案单调递减,且 \(i\) 对应的的答案 \(\le \lfloor \frac{n}{i} \rfloor\)

考虑设置阈值 \(S\),当 \(i \le S\) 时,直接每次 \(O(n)\) 暴力贪心,时间复杂度 \(O(Sn)\)。当 \(i > S\) 时,答案只有至多 \(O(\frac{n}{S})\) 种,于是对每种答案二分边界,确定其对应范围即可。单个范围需要 \(O(n \log n)\) 确定,所以时间复杂度 \(O(\frac{n^2 \log n}{S})\)

\(S = \sqrt{n \log n}\),最优理论时间复杂度为 \(O(n \sqrt{n \log n})\)

posted @ 2022-03-29 12:36  syksykCCC  阅读(517)  评论(0编辑  收藏  举报