2025.01.07 杂题记录
今天是好题选讲,顺便做了一些别的题目。
P3380 【模板】树套树
好,我终于搞明白树套树是怎么回事了,以前一直没做大概是因为平衡树好不太熟悉。
题目大意就是把普通平衡树的各种操作放在序列上,加上区间的限制。
树套树最普遍的做法就是线段树套平衡树。
考虑对线段树上的每一个节点都开一个平衡树,讲到这大概就会做了。
做法1:线段树以位置为索引,在平衡树中存放值。这样的做法,对于查询第 k 大则需要二分答案,时间复杂度是 \(O(n\log^3 n)\),空间复杂度是 \(O(n\log n)\),可能会被卡。
做法2:这是题解区的又一个线段树套平衡树的做法,我实现了这种做法。考虑离散化后,在线段树上以值为索引,往平衡树中存放位置,这样查询排名第 k 大就可以在线段树上二分。时间复杂度优化成了 \(O(n\log^2 n)\),空间复杂度 \(O(n\log n)\)。应该是最优的解法。
有了树套树后,我们就能在线地做带修改的二维数点,不过如果能离线做那么还是写分治吧。
P9036 「KDOI-04」挑战 NPC Ⅲ
好题选讲里的一道题,我也觉得非常好(又水一道紫)。
题目大意是求 \(n\) 个点的无向图中,大小为 \(n-k\) 的点独立集数量,\(k\le 18\)。
首先转化成求大小为 \(k\) 的点覆盖边的数量。
考虑到 \(deg>k\) 的点都必须选,不然这些邻边就需要大于 \(k\) 个点来覆盖它们。
对于剩下的未覆盖的边,每次选一个点最多覆盖 \(k\) 条边,所以当剩余边数大于 \(k^2\) 时一定无解。
因为边不多,且选的点很少,考虑爆搜,我们枚举每一条未被覆盖的边,然后选择其中的一些端点,使它可以被覆盖,过程中要使得确定为选的点数量小于等于 \(k\)。
设 \(c\) 为最后确定选的点数,\(s\) 为确定的点数(包括确定为选的和确定为不选的),则最后我们加上组合数 \(\binom {n-s} {k-c}\)。
时间消耗大致是 \(O(2^kk^2)\),可以去看题解中的证明。
CF848C Goodbye Souvenir
我们记 \(pre_i\) 表示上一个与 \(i\) 相同的位置,\(nxt_i\) 表示下一个与 \(i\) 相同的位置。
那么一个数第一次出现当且仅当 \(l\le i\le r\land pre_i< l\)。最后一次出现当且仅当 \(l\le i\le r\land nxt_i>r\)。
考虑到一次修改只会有 \(O(1)\) 个 \(pre,nxt\) 被改变,我们用 set
可以轻易维护出每次修改后 \(pre,nxt\) 的变化。
我们再把上面的条件加上时间一维,加上贡献的正负,之后跑 cdq分治 即可。时间复杂度 \(O(n\log ^2n)\)。