树上倍增可以比较容易求得i节点的第k个父亲,我们定义一个二维数组fa[i][j]代表节点i的第2^j个父亲,关于有什么用我们等会再说,现在先学会怎么去求这个fa数组

我们可以通过从根节点开始一遍dfs求得所有fa数组,首先我们发现fa数组有这样一个特性,fa[i][j] = fa[ fa[i][j-1] ][j-1],什么意思呢,就是说节点i的第2^j个父亲就是i的第2^(j-1)个父亲的第2^(j-1)个父亲,这看起来似乎是一句显然成立的废话,但我们可以通过这个特性以O(nlogn)的复杂度内求fa数组。

我们知道dfs是从根开始,一步一步往下走的,这就说明除了根节点,每个节点当它被dfs到的时候,它的所有父亲肯定都已经被dfs过了,这样通过刚才的关系,就可以由i的第2^(j-1)个父亲求fa[i][j]了,我们需要处理的只是i的第2^j个父亲有可能不存在罢了。我们初始化fa数组为0,然后从根开始dfs。若有n个节点,则显然一个节点最多只可能往前找2^log(n)个父亲

void dfs(int x)
{  for(int i=1;i<=logn;i++)  //logn代表log(n)if(fa[x][i-1])   //在dfs(x)之前,x的父亲们的fa数组都已经计算过了fa[x][i]=fa[fa[x][i-1]][i-1];  else break;    //x的第2^j个父亲可能不存在for(/*每一个与x相连的节点i*/)  if(i!=fa[x][0])     //如果i是x的儿子
        {  fa[i][0]=x;       //记录儿子的第一个父亲是x  dep[i]=dep[x]+1;      //深度
            dfs(i);  }
}  

求出fa数组后有什么用呢?其实我们可以轻易的在O(logk)内求出i的第k个父亲,根据数组定义看起来我们只能求i的第2,4,8...2^j次方个父亲,实际上我们可以求出i的第任意个父亲

我们有这样一个事实,任何一个数,都可以写成多个2的x次方的和,实际上这就是2进制转10进制的过程,比如:10的二进制表示为1010,它的左数第2位和第4位上是1,所以2^(2-1)+2^(4-1) = 2^1 + 2^3 = 10。这个思想很有用,需要记住

所以对于任意一个数k,只要我们把它写成若干个2的次方形式的数的和,就可以利用fa数组了。

另外我们代码中还有个技巧,(1<<i)&k表示k的二进制表示中,左数第(i-1)位上是否为1

经过上面知识我们可以写出求i的第k个父亲的代码

int father(int i,int k)
{  for(int x=0;x<=int(log2(k));x++)  if((1<<x)&k)    i=fa[i][x];     return i;
}  

转载于:https://www.cnblogs.com/chaoswr/p/8489224.html

树上倍增一些理解和写法相关推荐

  1. LCA(树上倍增 || rmqlca||)

    背景&&描述 给出一棵根节点为1的树,每次询问两点之间的最近公共祖先. 输入格式 第一行一个整数n表示树的节点个数 第二行n-1个数,第i个数表示点(i+1)的父亲是哪个点.保证第i个 ...

  2. LCA 最近公共祖先(RMQ、树上倍增、Tarjan),树上两点距离,线段重合长度

    对于LCA的一些理解 RMQ dfs处理树 对于一个树形结构,可以用dfs将一颗树转化成数组,数组中记录每个点的标号,这样数组就按照dfs的顺序把树存了下来 确定祖先的范围 对于询问的节点X和Y, X ...

  3. 牛客多校4 - Ancient Distance(树上倍增+dfs序+线段树)

    题目链接:点击查看 题目大意:给出一棵 n 个节点且以点 1 为根节点的的树,现在给出一个 k ,需要在树上选择 k 个关键点,使得 n 个点到达根节点的路径上,出现的最近的关键点的距离的最大值最小, ...

  4. 树上倍增求LCA及例题

    先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你 ...

  5. 树上倍增法求最近公共祖先LCA

    LCA,最近公共祖先,这个东西有很多作用,因此,如何高效求出LCA就成了一个热点的讨论话题. 下面所有的讨论都以图中这棵树为例子. 先来了解下什么是倍增吧,倍增其实就是二分的逆向,二分是逐渐缩小范围, ...

  6. 天梯赛 L2-030 冰岛人(LCA,树上倍增)

    链接 题面描述: 2018年世界杯,冰岛队因1:1平了强大的阿根廷队而一战成名.好事者发现冰岛人的名字后面似乎都有个"松"(son),于是有网友科普如下: 冰岛人沿用的是维京人古老 ...

  7. 对LCA、树上倍增、树链剖分(重链剖分长链剖分)和LCT(Link-Cut Tree)的学习

    LCA what is LCA & what can LCA do LCA(Lowest Common Ancestors),即最近公共祖先 在一棵树上,两个节点的深度最浅的公共祖先就是 L ...

  8. 主席树 + 树上倍增 ---- codeforces 587C[树上倍增或者主席树]

    题目链接 给定一棵n个点的树,给定m个人(m≤n)在哪个点上的信息,每个点可以有任意个人:然后给q个询问,每次问u到v上的路径有的点上编号最小的k(k≤10)个人(没有那么多人就该有多少人输出多少人) ...

  9. 关于树论【LCA树上倍增算法】

    补了一发LCA,表示这东西表面上好像简单,但是细节真挺多. 我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是 ...

最新文章

  1. 我是怎么通过技术白手起家创业的。
  2. 产品设计 产品经理 喜欢的网站
  3. [转]Objective-C 语言特性
  4. wps日期加减算天数_日期相减之后的天数怎么用公式计算 - 卡饭网
  5. GB2312、BIG5、GBK、GB18030简介
  6. Android网络请求框架Velley的用法与解析
  7. stm32点亮流水灯(小白的求学之路)
  8. Python相对导入:ValueError: attempted relative import beyond top-level package
  9. 人类一败涂地mac版(human fall flat中文版)
  10. 航运人工智能提升全球集装箱海陆各环节作业效率,箱管控,CIMCAI自动化集装箱况残损检测/箱信息识别数字化录入,智慧航运智能航运
  11. 郑州计算机网络安全协会,过滤王文档教材网吧使用手册(网吧)-郑州市计算机网络安全协会.doc...
  12. QAT量化感知训练(一)【详解】
  13. 牛顿法来解最大似然估计
  14. 嵌入式:浅析FinFET技术的发展前景
  15. 10.10 CF - 520B
  16. C++无法打开源文件
  17. 漂亮的PPT模板:三步搞定年终报告
  18. php显示大写金额,PHP数字金额转换成中文大写显示
  19. R 组合图形布局教程
  20. 大学生期末网页设计锦绣珠宝商城

热门文章

  1. 【Transformer】CrossFormer:A versatile vision transformer based on cross-scale attention
  2. android 揭示动画_遗传编程揭示具有相互作用的多元线性回归
  3. 【Android 修炼手册】Gradle 篇 -- Android Gradle Plugin 主要 Task 分析
  4. Java基本流程控制语句
  5. java关于泛型的实验代码_[改善Java代码]强制声明泛型的实际类型
  6. java 手写阻塞队列_Java阻塞队列的实现
  7. 如何在excel中判断某一点在某一区域内_SEM优化师常用的Excel表格函数集合
  8. c语言音像图书管理系统设计,c语言--图书管理系统
  9. 蓝字冲销是什么意思_梦见上学 做梦梦到上学是什么意思 梦到上学有哪些预兆...
  10. Ubuntu下安装 imagej 和 Fiji