倍增求lca
/*
节点维护的信息多样
如果用树状数组维护到根节点的边权或者点权, 可以直接插入点权和边权值,不需要预处理,
但是记得一定要使用ot[]消除影响.即差分. Housewife Wind 这个坑踩得死死得.
然后如果带修改,也可以线段树维护.
打上dfs序后, 其他的就是区间问题了. 然后查询 修改的时候,把dfs序与点或者边对应转换一下就OK了.
*/
int deep[maxn];
int up[maxn][];
int in[maxn]; // dfs序 入
int ot[maxn]; // dfs序 出
int pa[maxn]; // father 数组
int qsz, qtot; // 预处理出 deep[] in[] ot[] pa[] up[i][0]
void dfs(int u, int fa)
{
int i, v;
deep[u] = deep[fa] + ;
in[u] = qtot;
for (i=head[u]; i; i=edge[i].lst) {
v = edge[i].to;
if (v == fa) continue;
up[v][] = u;
pa[v] = u;
++qtot; // dfs序标号用.
dfs(v, u);
}
ot[u] = qtot;
} // 获取公共祖先的表.
void GetUp(int n)
{
int i, j;
for (j=; j<; ++j)
for (i=; i<=n; ++i)
up[i][j] = up[up[i][j-]][j-];
} // 倍增求lca
int lca(int u, int v)
{
if (deep[u] < deep[v]) swap(u, v);
int i, j, k = deep[u] - deep[v];
for (i=; i<; ++i) // 获取第k个祖先
if ((<<i) & k)
u = up[u][i];
if (u != v) {
for (i=; i>=; --i)
if (up[u][i] != up[v][i]) {
u = up[u][i];
v = up[v][i];
}
u = up[u][];
}
return u;
} int main()
{
// 多Cas记得清零 up[][] 之类的数组 还有全局变量
deep[] = ;
dfs(, );
GetUp(n); // 在dfs()预处理出各节点的父亲后调用. return ;
}
至于求解答案的几种, 一般也就那几种, 根据维护的信息来画个图,看怎么求解答案.
倍增求lca的更多相关文章
- 树上倍增求LCA(最近公共祖先)
前几天做faebdc学长出的模拟题,第三题最后要倍增来优化,在学长的讲解下,尝试的学习和编了一下倍增求LCA(我能说我其他方法也大会吗?..) 倍增求LCA: father[i][j]表示节点i往上跳 ...
- [算法]树上倍增求LCA
LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...
- 【倍增】洛谷P3379 倍增求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- hdu 2586 How far away ? 倍增求LCA
倍增求LCA LCA函数返回(u,v)两点的最近公共祖先 #include <bits/stdc++.h> using namespace std; *; struct node { in ...
- 倍增求lca模板
倍增求lca模板 https://www.luogu.org/problem/show?pid=3379 #include<cstdio> #include<iostream> ...
- 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)
洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...
- 倍增求LCA学习笔记(洛谷 P3379 【模板】最近公共祖先(LCA))
倍增求\(LCA\) 倍增基础 从字面意思理解,倍增就是"成倍增长". 一般地,此处的增长并非线性地翻倍,而是在预处理时处理长度为\(2^n(n\in \mathbb{N}^+)\ ...
- 树链剖分与倍增求LCA
树链剖分与倍增求\(LCA\) 首先我要吐槽机房的辣基供电情况,我之前写了一上午,马上就要完成的时候突然停电,然后\(GG\)成了送链剖分 其次,我没歧视\(tarjan LCA\) 1.倍增求\(L ...
- [学习笔记] 树上倍增求LCA
倍增这种东西,听起来挺高级,其实功能还没有线段树强大.线段树支持修改.查询,而倍增却不能支持修改,但是代码比线段树简单得多,而且当倍增这种思想被应用到树上时,它的价值就跟坐火箭一样,噌噌噌地往上涨. ...
- 树上倍增求LCA及例题
先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你 ...
随机推荐
- Django之用户认证功能
前言 做web应用对登录做用户身份认证,然后设置session是必不可少的,因为我们就需要把有权限访问本站视图的用户,单独建一张表记录到数据库里: Django作为一个大而全的框架,已经为我们做好了这 ...
- nginx源码安装教程(CentOS)
1.说明 官方源码安装说明:http://nginx.org/en/docs/configure.html 源码包下载地址:http://nginx.org/en/download.html 版本说明 ...
- for循环跳转语句(break、continue)
跳转语句用于实现循环执行过程中程序流程的跳转,在Java中的跳转语句有break语句和continue语句.接下来分别进行详细地讲解. 1. break语句 在switch条件语句和循环语句中都可以使 ...
- 实验:输入一篇英文新闻,以“#”结束,统计其中a-z这26个字母各出现的次数和总字符个数。(不区分大小写)
代码如下: #include <iostream> using namespace std; int main() { char ch; char s_letter[26]={'a','b ...
- py QScrollArea
# -*- coding: utf-8 -*-import jsonimport loggingimport sysimport requestsfrom PyQt5 import QtWidgets ...
- Vue + Element UI 实现权限管理系统 (功能组件封装)
组件封装 为了避免组件代码的臃肿,这里对主要的功能部件进行封装,保证代码的模块化和简洁度. 组件结构 组件封装重构后,试图组件结构如下图所示 代码一览 Home组件被简化,包含导航.头部和主内容三个组 ...
- sqlalchemy动态组合查询语句。
if filter_type == 1: search = and_(GameRoom.status ==1,or_( and_(GameRoom.white_user_id == user_id, ...
- Cracking The Coding Interview 5.5
#include <iostream> #include <vector> using namespace std; int getNum1(int N) { int num= ...
- 菜鸟翻译:国外的一个关于.net core的学习系列 第一天(安装并运行.NET core 到windox系统里面)
原文地址: Day 1 - Installing and Running .NET Core on a Windows Box 免责声明:我不是.NET Core 的团队成员.我使用的工具是公开可用的 ...
- 为什么不同网段的ip 不能直接通信
首先要明白一点,IOS一共七层, 发送数据的过程是从上到下,也就是从应用层一直到物理层,接受数据是从下至上. 来看你的问题,环境如下,我们来用一个ping命令的过程来解释:一个交换机,连两个电脑A和B ...