251222 lxl 讲题
P5607 [Ynoi2013] 无力回天 NOI2017
对元素出现次数进行根号分治。如果 \(cnt\ge B\),直接 bitset 暴力,否则把 \(nB\) 个二元组都搞出来直接哈希表维护。时间复杂度 \(O(\frac{n\sqrt n}{\sqrt w})\)。可以通过微调阈值卡过。
CF407E k-d-sequence
先按 \(a_i\bmod d\) 分为若干连续段,然后只需统计段内的贡献即可。一个段合法当且仅当 \(\frac{mx-mn}{d}\le \frac{r-l}{d}+k\)。于是对 \(r\) 扫描线,用线段树维护单调栈再加一个线段树上二分即可。
P8990 [北大集训 2021] 小明的树
发现合法当且仅当黑点形成一个连通块。于是用点数减边数进行刻画,只有这玩意取到最小值 \(1\) 的时候才合法。于是用线段树维护时间轴,以及维护最小值的贡献和。为了支持区间修改,需要记一下区间最小值的数量。
P7560 [JOISC 2021] フードコート (Day1)
区间加,区间 ckmax 和单点查询可以直接使用线段树维护。先把所有询问点到最终队尾的距离求出来,然后用另一棵线段树时光倒流进行简单维护即可。
CF1814F Communication Towers
考虑线段树分治,对每个点维护一个 tag 表示给并查集中的所有儿子都加上这个 tag。在合并 fa[x]=y 时执行 tag[x]-=tag[y],撤销时执行 tag[x]+=tag[y],修改直接 tag[find(1)]++ 即可。
P11706 「KTSC 2020 R1」穿越
对于一组 \(a,b\) 肯定就是线段树优化 dp 模板。考虑处理多组询问,可以把一种方案的代价表示为 \(ax+by\) 表示两种操作各用了 \(x,y\) 次。注意到我们只关心 \((x,y)\) 形成的下凸壳上的点。根据经典结论下凸壳的点数是不超过 \(V^{2/3}\) 的,其中 \(V\) 表示值域。于是直接线段树维护凸壳即可做到 \(O(n^{5/3}\log n+q\log n)\)。
P5608 [Ynoi2013] 文化课
为了支持区间推平数字,我们需要记录区间内加号和乘号形成的多项式。根据经典结论这种多项式的项数肯定是 \(O(\sqrt{len})\) 的。发现线段树上区间修改的 \(O(\log n)\) 段区间的多项式项数之和其实也是 \(O(\sqrt n)\) 级别的(等比数列)。因此怎么做时间复杂度都是对的。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | |
qoj1851 Directed Acyclic Graph
发现不比 DAG 可达性更容易,因此时间复杂度至少为 \(O(\frac{n^2}{w})\)。考虑操作分块,对一个块内的 \(B\) 个操作,我们希望对每个点求出最后一次赋值操作,以及赋值操作之后 ckmin 操作的权值最小值。前者直接拓扑排序即可,后者考虑将操作按照权值重新排序,用 bitset 维护可以到达某个点并且在时间 tm 之后的所有 ckmin 操作的 bitmask 然后直接取 lowbit 即可。
块长 \(B\) 取多少不会很影响复杂度,可以直接取 \(B=w\) 这样可以用 unsigned long long 代替 bitset。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | |
P7881 [Ynoi2006] rmpq
考虑操作分块,每 \(B=\sqrt n\) 个修改操作分一块。发现一个块会将整个平面分为 \(O(B^2)=O(n)\) 份。考虑如何求出 \(O(n)\) 个小块每块的 Data,考虑对时间分治,合并两个子问题可以做到 \(O(B^2)\),时间复杂度就是 \(T(n)=2T(\frac{n}{2})+O(n^2)\)。查询时把之前的所有块扫一遍,每个块内分别二分答案,操作次数是不带 \(\log\) 的。
为了进一步优化,考虑二进制分组 trick,这样合并的复杂度和分治是一样的,但是散块的 \(O(B)\) 个操作合并成了 \(O(\log B)\) 个块,可以让操作次数更少。
AT_abc369_g [ABC369G] As far as possible
发现贪心是对的,每次选最远的一个点加入,可以证明它一定不会被之后删掉。发现第一次取的是以 \(1\) 开头的长链,第二次取的是第二长的长链,以此类推。于是直接把所有长链搞出来排序即可。
P12462 [Ynoi Easy Round 2018] 星野爱久爱海
问题的关键是最大的最小斯坦纳树具有可合并性,然后随便维护区间信息就是对的。
我们尝试证明其可合并性。考虑证明向集合 \(S\) 中加入一个点 \(x\),不会向最优解中添加除了 \(x\) 之外的其它节点。由于插入 \(x\) 后点集的直径至少有一端是在原先的集合中,考虑以这个点为根进行长剖,分讨一下插入 \(x\) 之后的几种情况(可能会影响若干条长链),然后再分讨删掉的最短的那条重链在哪,感觉差不多能证出来。
由于具有结合律,所以可以用线段树维护。也可以 st 表套分块做到线性。
CF1476G Minimum Difference
发现出现次数只有不同的 \(O(\sqrt n)\) 种。因此直接带修莫队 \(O(\sqrt n)\) 回答单次询问做完了。
P9991 [Ynoi Easy Round 2023] TEST_107
简单支配对和线段树上二分。
P9809 [SHOI2006] 作业 Homework
简单根号分治