模板 树上求LCA 倍增和树链剖分
//233
模板 LCA
void dfs(int x,int f){
    for(int i=0;i<E[x].size();i++){
        int v = E[x][i];
        if(v==f)continue;
        deep[v]=deep[x]+1;
        lca[v][0]=x;
        for(int j=1;j<maxm;j++){
            int fa = lca[v][j-1];
            if(fa==0)continue;
            lca[v][j]=lca[fa][j-1];
        }
        dfs(v,x);
    }
}
int up(int x,int d)
{
    for(int i=maxm-1;i>=0;i--)
    {
        if(d<(1<<i))continue;
        x=lca[x][i];
        d-=(1<<i);
    }
    return x;
}
int Lca(int x,int y)
{
    if(deep[x]>deep[y])swap(x,y);
    y=up(y,deep[y]-deep[x]);
    if(x==y)return x;
    for(int i=maxm-1;i>=0;i--)
    {
        if(lca[x][i]!=lca[y][i])
            x=lca[x][i],y=lca[y][i];
    }
    return lca[x][0];
}
//树链剖分
#include <cstdio>
#include <cstdlib>
#define maxm 200010
struct edge{int to,len,next;}E[maxm];
int cnt,last[maxm],fa[maxm],top[maxm],deep[maxm],siz[maxm],son[maxm],val[maxm];
void addedge(int a,int b,int len=0)
{
    E[++cnt]=(edge){b,len,last[a]},last[a]=cnt;
}
void dfs1(int x)
{
    deep[x]=deep[fa[x]]+1;siz[x]=1;
    for(int i=last[x];i;i=E[i].next)
    {
        int to=E[i].to;
        if(fa[x]!=to&&!fa[to]){
            val[to]=E[i].len;
            fa[to]=x;
            dfs1(to);
            siz[x]+=siz[to];
            if(siz[son[x]]<siz[to])son[x]=to;
        }
    }
}
void dfs2(int x)
{
    if(x==son[fa[x]])top[x]=top[fa[x]];
    else top[x]=x;
    for(int i=last[x];i;i=E[i].next)if(fa[E[i].to]==x)dfs2(E[i].to);
}
void init(int root){dfs1(root),dfs2(root);}
int query(int x,int y)
{
    for(;top[x]!=top[y];deep[top[x]]>deep[top[y]]?x=fa[top[x]]:y=fa[top[y]]);
    return deep[x]<deep[y]?x:y;
}
int n,m,x,y,v;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);addedge(x,y,v);addedge(y,x,v);
    }
    init(1);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",query(x,y));
    }
    return 0 ;
}												
											模板 树上求LCA 倍增和树链剖分的更多相关文章
- 洛谷P3379 【模板】最近公共祖先(LCA)(树链剖分)
		
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
 - 4.12 省选模拟赛 LCA on tree 树链剖分 树状数组 分析答案变化量
		
LINK:duoxiao OJ LCA on Tree 题目: 一道树链剖分+树状数组的神题. (直接nQ的暴力有50. 其实对于树随机的时候不难想到一个算法 对于x的修改 暴力修改到根. 对于儿子的 ...
 - BZOJ 3626   LCA(离线+树链剖分+差分)
		
显然,暴力求解的复杂度是无法承受的. 考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案.观察到,深度其实就是上面有几个已 ...
 - BZOJ-3626:LCA(离线+树链剖分)
		
Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q ...
 - HDU 3966 Aragorn's Story(模板题)【树链剖分】+【线段树】
		
<题目链接> 题目大意: 给定一颗带点权的树,进行两种操作,一是给定树上一段路径,对其上每个点的点权增加或者减少一个数,二是对某个编号点的点权进行查询. 解题分析: 树链剖分的模板题,还不 ...
 - HYSBZ 1036树链剖分
		
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从 ...
 - [树链剖分]BZOJ3589动态树
		
题目描述 别忘了这是一棵动态树, 每时每刻都是动态的. 小明要求你在这棵树上维护两种事件 事件0: 这棵树长出了一些果子, 即某个子树中的每个节点都会长出K个果子. 事件1: 小明希望你求出几条树枝上 ...
 - Something about 树链剖分
		
声明:部分思路与图片源于OI Wiki 关于树链剖分 树链剖分用于将树分割成若干条链的形式,以维护树上路径的信息. 树链剖分有多种形式,如 重链剖分,长链剖分 和用于 $LCT$ 的剖分,大多数情况下 ...
 - 【bzoj2238】Mst(树链剖分+线段树)
		
2238: Mst Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 465 Solved: 131[Submit][Status][Discuss] ...
 
随机推荐
- bzoj千题计划201:bzoj1820: [JSOI2010]Express Service 快递服务
			
http://www.lydsy.com/JudgeOnline/problem.php?id=1820 很容易想到dp[i][a][b][c] 到第i个收件地点,三个司机分别在a,b,c 收件地点的 ...
 - [转载]AngularJS 指令 用法
			
http://book.2cto.com/201312/37782.html http://www.itnose.net/detail/6144038.html http://www.cnblogs. ...
 - [转载]微软VS2015支持Android和iOS编程
			
Visual Studio 2015 Preview http://www.zhihu.com/question/26594936/answer/33397319 http://www.visuals ...
 - Integer中1000==1000为false而100==100为true
			
查看Integer.java类,会发现有一个内部私有类,IntegerCache.java,它缓存了从-128到127之间的所有的整数对象.如果在这个区间内,他就会把变量当做一个变量,放到内存中:但如 ...
 - 深入浅出js事件
			
深入浅出js事件 一.事件流 事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念是为了解决页面中事件流(事件发生顺序)的问题. <div id="outer"> & ...
 - 数链剖分(Tree)
			
题目链接:https://cn.vjudge.net/contest/279350#problem/D 题目大意:操作,单点查询,区间取反,询问区间最大值. AC代码: #include<ios ...
 - H - Tickets  dp
			
题目链接: https://cn.vjudge.net/contest/68966#problem/H AC代码; #include<iostream> #include<strin ...
 - 【CTF REVERSE】WHCTF2017-CRACKME
			
1.前言 假装大学生水一下CTF题目,常规思路.程序没有加壳,是VC写的MFC程序. 2.破题思路 1.MessageBox 下断点 2.找到提示错误字符串的函数B 3.跟踪函数 4.跟踪算法 3.实 ...
 - oracle赋某表truncate权限
			
一.ins用户下创建存储过程 二.mobapp用户下赋权:执行存储过程的权限 三.odso_insert用户下执行存储过程,即可truncate表 查看odso_insert用户拥有的权限 一.ins ...
 - lombok使用说明
			
简介lombok 的官方网址:http://projectlombok.org/lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码.特别是相对于 POJO, ...