数据结构杂题集

Codechef SD ER

• 给出一棵树,维护点集 𝑆(加点删点)

• 如果 𝑆 的大小是偶数,输出:如果将 𝑆 中的点两两连上边权为树
上距离的边,那么 𝑆 里的最小权完美匹配是多少
• 𝑛, 𝑞 ≤ 10^6


考虑边的贡献

交叉一定不优,所以

一条边有贡献当且仅当两侧各有奇数个点

也就是子树里有奇数个点

点删除增加的时候就是对到根的链上边权值变成0或者变回自己

LCT维护,维护存在边、不存在边权值和,打“取反”标记即可。

 

经典问题

• 给出一张无向图
• 每次删掉一个点,求图中边双连通的点对个数
• 𝑛, 𝑚 ≤ 10^6

时光倒流。删点变成加点

再把加点改成加边

如果只询问连通性的话,并查集就可以做

边双联通和一般连通性的共同性质是:有传递性(x=y,y=z,则x=z)

一个并查集维护连通性,两棵树连通的时候,启发式合并,把相连的点作为小树的根,再连上去

另一个并查集进行路径压缩,维护边双。连接树上两个点,把两个点到LCA路径上的点合并起来,并查集路径压缩一下加速。

至于连接两棵树,第二个并查集怎么办:暴力重新把相关的边连接一下,所以启发式合并的条件是:非树边+树边的总和小

找LCA暴力倍增就是log^2了

可以LCT强行维护。先access(a),再access(b) 这个时候第一个连接的点就是LCA

 

 

ICPC HK 2018 

• 刚开始你有 𝑛 个序列,刚开始序列都是长度为 1 的
• 每次支持拼接两个序列,问每个序列的每个子区间的最小值的和
• 𝑛 ≤ 10^6

笛卡尔树,

每个点的贡献就是左右儿子sz乘积

拼接?笛卡尔树合并

定义关键点:一个树最左边和最右边两个链

关键点只有初始的O(n)个

合并x,y时候,对于x的右链和y的左链,从最底下开始往上找到第一个能放的位置,这一段长度设为len

之后这段关键点会被覆盖住,不再存在。

然后y的这个点左儿子和x的这个点的右儿子进行类似fhq的合并,也就是一般的暴力合并

由于路径上的点就是两个段的关键点

关键点然后就消失了。

走的长度就是关键点减少的个数

所以均摊O(n)

从最底下开始找,可以用链表然后链表合并。单纯记录每个点最右边的点也可以

sz什么的pushup就找到了。

(pushup这个不太好找到,最开始一段链很难搞。可以用LCT同时和笛卡尔树合并做,用于打上标记)

挺trick的

 

posted @ 2019-02-14 10:05  *Miracle*  阅读(443)  评论(0编辑  收藏  举报