SDWC day4 - 树上数据结构
T1
结论推式子,分开考虑每一次操作改变的贡献。
T2
k=2 是类似于猫树的思想。
对于一段区间 [l,r],我们找到中点 mid
处理出 每个后缀 x \in [x, mid] 到 mid 的答案,每个前缀 x \in [mid + 1, r] 到 mid 的答案。
然后对于左半区间的点到右半区间的点就可以通过一次中转点到达了。
然后递归左右区间即可。
k = 3 是分块分成三块?像上面那样搞?预处理每个块后缀前缀的答案,整块的答案。
T3
启发式合并
合并的时候用哈希表可以实现 O(1) 合并。
然后就可以 O(n logn) 做了。
LG - T11738
把修改的区间全都离线下来,一共为 \(a \log n + b\) 个。
然后对所有区间进行桶排。
然后把所有询问分离扫一遍就可以了。
LG - 5314
- n 根号 log 做法
把度数 > 根号 n 的点分为一类(大点),其他的分为一类(小点)
对于每一个大点,我们可以用平衡树去维护。
对于每个小点,我们在查询的时候暴力查即可。
- n log^2 n 做法
树链剖分,平衡树维护一圈节点,但是不维护自己父亲和重儿子。然后对于链加的操作,发现修改的都是他们重儿子、父亲、和自己。
唯一需要修改平衡树内的点的时候是从一个链跳到另外一个链的时候。然后这种时刻只有 log 次,所以修改起来是 log^2 的。
[Ynoi????] TEST_68
先跑出全部点的一组最大的 x, y。
然后 x 到根节点,y 到根节点这两条路径是还没有确定的。
然后对于这两条路径,从上向下遍历,把点依次插入 01trie 顺便查最大值就 ok 了。
LG-P6072
如果做一个树上前缀和,那么就可以转化成路径端点的异或和。
我们考虑枚举每个子树。
子树内选一对点,子树外选一对点,就可以做到路径不交了。
子树外选一对点可以是上面这道题的做法。
对于子树内选一对点,可以用启发式合并 + Trie
复杂度是 n log^2 n 的。
我们尝试用上面的套路把他优化到单 log。
如果我们选了一条最大的链 (x,y),那么只能从 x 到根节点,y 到根节点这两个路径旁边的子树去找了
我们遍历每个子树直接用过 Trie 去加进去做即可,总共只会加删 n 次。
如果我们不选这条最大的链呢,
我们只要从下向上枚举点,每次把新增的节点加进 Trie 即可。
一共要这样做两次,加入点的树也是 O(n) 级别。
然后就做完了。
Loj 6276
首先枚举所有颜色、
枚举同种颜色的对。
假设有两个点 x, y, 那么如果一条链一个端点在 x 的子树内,另一个端点在 y 的子树内,那肯定是不合法的对吧。
然后我们考虑用更复杂的方式约束。
我们转化到 dfs 序上。
两端区间可以转化到二维平面,
也就是二维平面的某个矩阵是不合法的。
然后把所有这种情况都搞出来放上去
求一个矩阵面积并然后一减就做完了。
bzoj 3159
发现瓶颈在于如何做 5 操作。
用树链剖分把树排成序列,然后一个 5 操作会涉及 log 个区间,把这 log 个区间拿出来扔进一个 Splay 里,打个翻转标记。
然后在按照 log 个区间的大小分割回去就做完了。
CF1017G
先不考虑 2 操作
可以把 1 操作加到单点上,
对于一个 3 操作询问 x
我们如果找到一个 x 到 根的后缀,满足权值和 >= 这个后缀的长度,就说明它是黑色
我们把所有点初始化为 -1 就可以解决。
然后考虑 2 操作。
显然不能直接区间清楚,因为有的权值在 x 到根节点这条路径上。
我们可以查一下根节点的路径最深延伸到了 x 子树内多深,然后在 x 这个位置减去延伸的深度,就相当于删掉了。
线性空间区间众数
原题:P5048 [Ynoi2019 模拟赛] Yuno loves sqrt technology III
用 vector 存每个值的位置集合。
假设现在的答案为 a,如果 x 出现 a+1 次,那么便可以更新
我们可以转化成 x 在集合中的位置,然后向后延伸 a 个后的位置是不是 <= 这次询问的区间 r。
如果是的话表示答案可以更新。
空间复杂度 O(n)
好像还要套上值域分块。
时间复杂度 O((n+m) \sqrt n)