首页 > TAG信息列表 > dsu

树上启发式合并(dsu on tree)

DSU on Tree and It's questions 树上启发式合并,可以在 \(O(n\log n)\) 的时间复杂度内解决一类对于子树的查询问题。这篇文章以题目为主。 算法流程 遍历 \(u\) 的所有轻儿子,计算答案,但不保留其在一个全局的数据结构内的结果。 遍历 \(u\) 的重儿子,保留它对一个全局数据结构的影

并查集(dsu)

一共有 n 个数,编号是 1∼n ,最开始每个数各自在一个集合中。 现在要进行 m 个操作,操作共有两种: M a b,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作; Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中; 输入格式 第一行输入整数 n 和 m

ABC EF 板刷笔记

菜鸡的刷题记录owo!偶尔也会更一些高质量D题。 ABC264 E 比较秒的一道题。 首先将操作反向处理,将摧毁变为修建,跑dsu维护答案即可。 总之就是先检查在不在一个连通块,然后发电厂就完了。

启发式合并和DSU on tree入门

启发式合并 定义 一个基于直观或经验构造的算法,在可接受的花费(指计算时间和空间)下给出待解决组合优化问题每一个实例的一个可行解,该可行解与最优解的偏离程度一般不能被预计。 举个栗子:并查集的按秩合并。 每次我们将大集合合并到小集合里,新集合至少为大集合的两倍,每次合并都会变

浅谈树上启发式合并(DSU on tree)

先看例题 CF600E Lomsat gelral 链接 对于这道题,我们要对每一个子树进行查询。观察一下,很容易想到通过信息的合并让父节点继承子节点的信息。但是对于每个点都开一个桶会MLE sol1 线段树合并 对于每一个节点都开一个线段树,然后进行线段树合并即可。这样做虽然足以通过本题,但空间巨

dsu on tree

子树类查询问题 dsu on tree和长链剖分都是解决子树类静态查询问题的统计类算法。 这类问题首先要是“子树”查询,并且是“静态”不带修改的。 注意某些问题其实不太有必要上dsu on tree,比如子树元素和,子树元素最大值之类的。(可合并区间信息) 例如子树众数,子树元素种类数这些不可合

树上启发式合并(dsu on tree)学习笔记

树上启发式合并(dsu on tree)学习笔记 闲话 树上启发式合并,又称 dsu on tree(虽然跟 dsu 并查集完全没关系),用于离线处理子树相关询问。 它是一种利用了重链剖分性质的暴力,时间复杂度为完全正确的 \(\mathcal{O}(n\log n+m)\),个人认为跟莫队等都是非常优雅的暴力。 阅读本文并不需要重

leetcode(c++)(并查集)

#include <iostream> #include <vector> using namespace std; class DSU{ public: vector<int>parent; DSU(int n) { parent = vector<int>(n); for(int i = 0; i< n; ++i) { parent[i] =

[dsu on tree] 2020CCPC长春F Strange Memory

首先考虑枚举lca的做法,对于每一个lca枚举其子树中所有节点,时间复杂度$O(n^2)$显然过不了 再思考发现这是一个针对子树的询问操作,考虑dsu on tree来统计答案 开一个新数组vec[x],其中x为权值,记录了所有权值为x的编号 那么只需要每次计算一颗新子树时,先累加答案,再更新vec数组(如果同时

dsu on tree

算法简介 \(\quad\)前置知识:树链剖分 \(\quad\)dsu on tree 利用了树链剖分将重儿子先剖出来,然后在查询的时候先遍历轻儿子,然后将轻儿子所求的值删去(以免影响它的兄弟),最后求出重儿子,重儿子的贡献值因为是最后一个,所以不用清空,最后如果本节点是轻儿子,则清空自己,本节点是重儿子,则保

Dsu on tree

dsu on tree学习笔记 (\(\uparrow\) 学习参考) 一般来说,Dsu on tree 大多可以和 点分治 互相换着用,都是处理子树或以 \(x\) 为根的路径等问题。 这种问题假设好状态基本上可以秒了。 咕咕咕

Codeforces Round #762 (Div. 3) G. Unusual Minesweeper

题目 原题地址:G. Unusual Minesweeper 题目编号:1619G 目标算法:贪心、并查集 难度评分:2000 1.题目大意 有 n 个雷,每个雷都有自己的坐标 (x, y) 以及爆炸时间 所有雷都会按照 “+” 的形状爆炸,四个方向的波及范围均为 k 一个雷爆炸后如果其爆炸范围内有其他雷,则被波及的雷也会在

【题解】CF1284G Seollal

前置芝士:拟阵交 如果你会,请跳过。 一切证明都略去了……如果需要的话我以后整理一个详细点的吧…… 拟阵的定义 我们记一个拟阵(Matroid) \(\mathcal M = \langle S,\mathcal I\rangle\)。 其中,我们称 \(S\) 为 Ground Set,\(\mathcal I\) 为 Family of Sets。 请注意此处的 \mathcal

学习笔记:树上启发式合并(dsu on tree)

DSU on tree ! 解决树上问题的利器,复杂度虽然没有长链剖分优秀,不过思考简单而且代码优美,是树上维护答案的好帮手。 例题:DSU on tree 应用范围 解决一些子树的离线静态问题,巧妙地将暴力 \(O(n^2)\) 的复杂度优化到 \(O(nlogn)\)。 算法思路 回溯整棵树维护子树大小以及重儿子,为后

牛客练习赛91 C.魔法学院(hard version) (dsu区间染色)

离线将所有信息存下来,按照字符的大小排序,不难发现,字符ascii越大的最后覆盖最优,那么我们选最大的覆盖,同时并查集维护覆盖过的区间,即让每个节点的父亲都等于它右边的节点,对于每个区间我们跑\([l_i,r_i]\),每次更新\(l\)为\(p[l+1]\),这样遇到覆盖过的区间就直接跳过,那么复杂度为\(O(n+

DSU on tree

存一下,可以用来对比找bug #include<bits\stdc++.h> using namespace std; #define int long long void in(int &x){ int y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<=�

Dsu on tree 和 点分治

写的有点乱,意识流 blog /yun 感谢 @Mr_Spade 对我的帮助。 从 Dsu on tree 到点分治 Dsu on Tree 的主要思想是轻重链剖分,使每个点作为根时,都继承重儿子的信息并快速加入根的影响,并对每个轻儿子暴力向重儿子合并。由于每个点被合并 \(O(\log n)\) 次,复杂度是正确的。 这种问题也可

qbxt

d1:t1暴力 t2一开始看成l-r里随便选单个数异或小于x的数了,这个可以倍增归约二分套线段树,复杂度一个log 考虑对c排序,每次找差量,统计答案 对原序列差分,问题转化为每次异或两个点 然后我们发现除非两个点都被更新过否则直接乘 如果两个都更新过那么就找大的那个乘起来 然后你发现wa了,

线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

题目链接 题目大意 解题思路: 我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是 O ( n

E - Moat(状压&DSU)

E - Moat(状压&DSU) 考虑每个位置是在区域内还是区域外,每个合法答案与区域的分布情况一一对应。 先状压,然后所有包含给定输入的情况,先将 4 × 4 4\times

U41492 树上数颜色(dsu on tree)

blackpink \(O(n^2)\)显然不过我们应该优化成\(O(nlogn)\) 采用树上启发式合并 仿照树链剖分的思想,对于每一个位置,我们先处理所有的轻儿子,然后处理重儿子,统计当前节点的答案,最后把轻儿子删掉就可以了。 这样全局一个桶就够用了。 #include<iostream> #include<cstdio> #include<al

浅谈dsu on tree

前言:dsu on tree利用了树链剖分将重儿子先剖出来,然后在查询的时候先遍历轻儿子,然后将轻儿子所求的值删去(以免影响它的兄弟),最后求出重儿子,重儿子的贡献值因为是最后一个,所以不用清空,最后如果本节点是轻儿子,则清空自己,本节点是重儿子,则保留,依次。 dsu on tree利用了重儿子的性质,尽量

CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

题面传送门 这道题是dsu on tree的板子题。 我们考虑如果一个子串状压后1的个数小于等于\(1\)那么就肯定是回文串。 然后两个点之间路径的异或值就是两个点的前缀异或值。 那么直接dsu on tree即可。 dsu on tree的流程大概是先dfs轻子树然后删除贡献,然后dfs重子树保留贡献,然后dfs

Note -「Dsu On Tree」学习笔记

前置芝士 树连剖分及其思想,以及优化时间复杂度的原理。 讲个笑话这个东西其实和 Dsu(并查集)没什么关系。 等等好像时间复杂度证明伪了?? 算法本身 Dsu On Tree,一下简称 DOT,常用于解决子树间的信息合并问题。 其实本质上可以理解为高维树上 DP 的空间优化,也可以理解为暴力优化。 在这

CF570D Tree Requests 树上差分/dsu on tree

判断能否构成回文很简单,出现次数为偶数的不用管,出现次数为奇数的最多有一个 可以用状压储存出现次数的奇偶情况,判断的时候 puts(ans[i]==(ans[i]&(-ans[i]))?"Yes":"No"); 这里用到了树状数组的lowbit求法 解法一:dsu on tree裸题详情请见这里 解法二:树上差分 划重点:能用这种方法是