LCA__st算法&&树上倍增】的更多相关文章

st表 #include<cstdio> #include<algorithm> #include<cmath> using namespace std; ]; ]; ]; ]; ][]; ]; ]; ]; int ecnt,cnt,m,n,s,x,y,a,b; void add(int u,int v) { //建链前 go[++ecnt]=v; nxt[ecnt]=adj[u]; adj[u]=ecnt; } void dfs(int u,int pre) { de…
LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4)一个点地一个点地往上跳,直到到某个点(3)和另外那个点(5)的深度一样 然后两个点一起一个点地一个点地往上跳,直到到某个点(就是最近公共祖先)两个点“变”成了一个点 不过有没有发现一个点地一个点地跳很浪费时间? 如果一下子跳到目标点内存又可能不支持,相对来说倍增的性价比算是很高的 倍增的话就是一次…
题意:给你一个n个点m条边的图,有若干组询问,每次询问会选择图中的一些边删除,删除之后问此图是否联通?询问之间相互独立.此题强制在线. 思路:首先对于这张图随便求一颗生成树,对于每一条非树边,随机一个权值.树边的权值为所有覆盖这条树边的非树边的权值异或和.覆盖是指这条边是个返祖边,并且一端在父节点方向,一端在子节点方向.这样,我们选出若干条边,看一下他们异或起来是不是0,如果是0,那么相当于把一条树边和它的所有子节点方向的返祖边全部断开,那么图就不连通了. 代码: #include <bits/…
题目描述 给一个树,n 个点,有点权,初始根是 1. m 个操作,每次操作: 1. 将树根换为 x. 2. 给出两个点 x,y,从 x 的子树中选每一个点,y 的子树中选每一个点,如果两个点点权相等,ans++,求 ans. 输入 第一行两个数表示 n,m. 第二行 n 个数,表示每个点的点权 a[i]. 之后 n - 1 行 , 每行两个数 x , y , 表示一条边 之后 m 行,每行为 1 x 或者 2 x y. 1 x,表示将根变成 x点. 2 x y,表示查询 x 点的子树与 y 点的…
Update: 2019.7.15更新 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 重要事情说三遍!!!!! 2019.7.16更新 笔记再次完善,感谢[Ichinose]大佬提出的好问题,并且修改了代码部分的错误注释. 笔记再次完善,感谢[Ichinose]大佬提出的好问题,并且修改了代码部分的…
补了一发LCA,表示这东西表面上好像简单,但是细节真挺多. 我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是说f[0][x]是父亲,f[1][x]是爷爷,f[2][x]是高祖父(爷爷的爷爷),f[3][x]是远祖父(高祖父的高祖父) 搞个事: 按古制辈份分为:自己,父亲.祖父.曾祖.高祖.天祖.烈祖.太祖.远祖.鼻祖. 扯回来,这个就是倍增的思想,可以方便的实现O(logn)的LCA,现在让你在构图的时候…
先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你不会吧:unamused:...) 思想 树上倍增嘛,顾名思义就是倍增 相信倍增大家都不默认,著名的rmq问题的$O(n*logn)$的解法就是利用倍增实现的 在树上倍增中,我们用 $f[j][i]$表示第$j$号节点,跳了$2^j$步所能到达的节点 $deep[i]$表示$i$号节点的深度 然后用…
第一种:树上倍增 f[x,k]表示x的2^k辈祖先,即x向根结点走2^k步达到的结点. 初始条件:f[x][0]=fa[x] 递推式:f[x][k]=f[ f[x][k-1] ][k-1] 一次bfs预处理f数组(nlogn),然后每次询问都可以在(logn)时间内求出x,y的lca 求lca的步骤 1.令x的深度大于y,然后通过二进制拆分将x上调到与y同一个深度(依次用k=2^logn,...2^1,2^0试探) 2.如果此时x==y,那么y=lca(x,y),算法结束 3.继续用第一步的二进…
LCA就是最近公共祖先,比如 节点10和11的LCA就是8,9和3的LCA就是3. 我们这里讲一下用树上倍增来求LCA. 大家都可以写出暴力解法,两个节点依次一步一步往上爬,直到爬到了相同的一个节点. 二树上倍增就是对暴力的优化,改成了一次爬好几步. 具体怎么爬呢?就是两个点每次爬 2^j 步,而 j 满足的是两个点爬到的点不能相同,因为这样可能是公共祖先,但不一定是最近的.在这种条件下要使 j 尽可能的大. 举个例子,比如上图的节点7和8,当 j = 2 时,都爬到了节点 1,然而很显然这不是…
[题目]E. NN country [题意]给定n个点的树和m条链,q次询问一条链(a,b)最少被多少条给定的链覆盖.\(n,m,q \leq 2*10^5\). [算法]树上倍增+二维数点(树状数组) 先从半链角度考虑.将每条给定链和每个询问拆成向上的一段和向下的一段.那么假设询问的半链最低端节点为x,贪心地选择x子树内向上延伸最远的给定半链(假设最高点为y),再从y继续贪心直至超过半链最顶端节点.再只考虑半链的前提下贪心显然正确. 但是我们注意到,这样贪心的复杂度是不正确的,因为如果每次只跳…