前言 已经是第三次遇到原题. 第一次是在 J O I 2021 S p r i n g C a m p \rm JOI2021~Spring~Camp JOI2021 Spring Camp 里遇到的类似的题(Food Court),我当初就用的启发式合并平衡树做法,但是由于常数不够优,没能通过 2 e 5 \tt2e5 2e5 的测试点.当时就只能用线段树合并做, O ( n log ⁡ n ) \rm O(n\log n) O(nlogn) ,但是我不会. 第二次是在打 C E O I 20…
题目描述 N个点,形成一个树状结构.有M次发放,每次选择两个点x,y,对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入 第一行数字N,M接下来N-1行,每行两个数字a,b,表示a与b间有一条边再接下来M行,每行三个数字x,y,z.如题 输出 输出有N行每i行的数字表示第i个点存放最多的物品是哪一种,如果有多种物品的数量一样,输出编号最小的.如果某个点没有物品则输出0 样例输入 3 21 21 31 3 12 3 2 样例输出 121 题解…
Gold is everywhen! - somebody 启发式合并 将小的集合一个个插入到大的集合. 每次新集合大小至少比小集合大一倍,因此每个元素最多合并\(\log n\)次,总复杂度为\(n\log n\) × 插入复杂度. splay合并 将小的splay按中序遍历一个个插入到大的splay. 可证明复杂度为\(O(n\log n)\). 没什么特殊的应用. 线段树合并 int merge(int x, int y, int l, int r) { if(!~x) return y;…
启发式合并 有\(n\)个集合,每次让你合并两个集合,或询问一个集合中是否存在某个元素. ​ 我们可以用平衡树/set维护集合. ​ 对于合并两个\(A,B\),如果\(|A|<|B|\),那么我们就把\(A\)中的每个元素暴力加到\(B\)中,否则就把\(B\)中的元素暴力加到\(A\)中. ​ 对于一次把\(A\)中的每个元素暴力加到\(B\)中的操作,\(|A|\)会变成\(|A|+|B|\),也就是说大小至少会翻倍,所以一个元素最多被暴力插入\(\log n\)次.每次插入的时间复杂度是…
这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例,submit,1A! 哇真的舒服 调试输出懒得删了QwQ #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<queue> #include…
题目大意:给你一些点,修改是在在两个点之间连一条无向边,查询时求某个点能走到的点中重要度第k大的点.题目中给定的是每个节点的排名,所以实际上是求第k小:题目求的是编号,不是重要度的排名.我一开始差点被这坑了. 网址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 这道题似乎挺经典的(至少我看许多神犇很早就做了这道题).这道题有两种写法:并查集+(splay启发式合并or线段树合并).我写的是线段树合并,因为……splay不会打+懒得学.…
好久没更新博客了,前段时间一直都在考试,都没时间些,现在终于有点闲了(cai guai)... 写了一道题,[HNOI2012]永无乡,其实是一道板子题,我发现我写了好多板子题...还是太菜了... 这道题有两个操作,合并和查询第k小,合并可以用到启发式合并,查询是平衡树,我这里写的是Splay+启发式合并. 启发式合,其实就是暴力合并,做法是将要合并的两个节点分别旋转到根,再把size小的拆掉,暴力插入到另一棵树里.这样做的复杂度是O(logn(拆散一棵树)*logn(插入另一棵树)),即O(…
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛.如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的.现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥.Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪…
题目链接 考虑树退化为链的情况,就是求一个最长(严格)上升子序列. 对于树,不同子树间是互不影响的.仿照序列上的LIS,对每个点x维护一个状态集合,即合并其子节点后的集合,然后用val[x]替换掉第一个大于它的数(有等于的就不换了). 最后根节点状态集合的大小就是答案了. 关于替换数,可以先找到这个数的位置,如果有这个数就不用管了:没有的话插入进去,然后递归回去,找到一个靠右的位置删掉. 当然其实不用线段树合并这么麻烦,直接上multiset启发式合并就可以了.. 注意是合并了子树的状态,so叶…
标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) https://www.lydsy.com/JudgeOnline/problem.php?id=3473 题解: 先讲三个做法公共部分: 建出广义SAM,然后对于每个点求出它在多少字符串中出现过. 做法一 把每个字符串在广义SAM上暴力跑.每跑到一个点就暴力沿着fail树往上跳,标记跳过的点,直…