树上倍增LCA模版

void dfs(int u){
    for(int i = head[u];i!=-1;i = edge.next){
        int to = dege[i].to;
        if(to == p[u][0])
           continue;
        d[to] = d[u]+1;
        dis[to] = dis[u]+edge[i].w;
        p[to][0] = u;
        dfs((to));

    }
}
void init(){
    for(int j = 1;(1<<j)<=n;j++)
       for(int i = 1;(1<<i)<=n;i++){
           p[i][j] = p[p[i][j-1]][j-1];
       }
}
int lca(int a,int b){
    if(d[a]>d[b]) swap(a,b);//b在下面;
    int f = d[b]-d[a];//f是高度差;
    for(int i = 0;(1<<i)<=f;i++)
       if(((1<<i))&f)
          b = p[b][i];
    if(a!=b){
        for(int i = (int lomg2(n));i>=0;i--)
            if(p[a][i]!= p[b][i])//从最大的祖先开始,判断a,b的祖先是否相同
               a = p[a][i],b = p[b][i];//如果不相同,a和b同时向上移动2^j
        a = p[a][0];
    }
    return a;
}
时间: 2024-10-16 19:51:03

树上倍增LCA模版的相关文章

【bzoj4281】[ONTAK2015]Zwi?zek Harcerstwa Bajtockiego 树上倍增+LCA

题目描述 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点.之后你将依次收到k个指令,每个指令包含两个整数d和t,你需要沿着最短路在t步之内(包含t步)走到d点,如果不能走到,则停在最后到达的那个点.请在每个指令之后输出你所在的位置. 输入 第一行包含三个正整数n,m,k(1<=m<=n<=1000000,1<=k<=1000000). 接下来n-1行,每行包含两个正整数x,y(1<=x,y<=n),描述一条树边. 接下来k行,每行两个整数d,t

[HNOI2014][BZOJ3572] 世界树|虚树|树上倍增LCA|树型dp|dfs序

3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 555  Solved: 319[Submit][Status][Discuss] Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石.    世界树的形态可以用一个数学模型来描述:世界树中有n个种

【BZOJ-4281】Zwi?zek Harcerstwa Bajtockiego 树上倍增LCA

4281: [ONTAK2015]Zwi?zek Harcerstwa Bajtockiego Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 167  Solved: 70[Submit][Status][Discuss] Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点.之后你将依次收到k个指令,每个指令包含两个整数d和t,你需要沿着最短路在t步之内(包含t步)走到d点,如果不能走到,则停在最后到达的那

hdu2856(倍增lca模版题)

ac代码: #include<bits/stdc++.h> using namespace std; #define per(i,a,b) for(int i=a;i <= b;i++) #define Max(a,b) a=max(a,b) #define Min(a,b) a=min(a,b) #define Sz(x) (int)x.size() typedef long long ll; ll gcd(ll a,ll b){while(b){ll t=b;b=a%b;a=t;}r

[SDOI2011][BZOJ2286] 消耗战|虚树|树型dp|树上倍增LCA

2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1040  Solved: 363[Submit][Status][Discuss] Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望.已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸

[SDOI2015][BZOJ3991] 寻宝游戏|set|dfs序|虚树|树上倍增LCA

3991: [SDOI2015]寻宝游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 427  Solved: 212[Submit][Status][Discuss] Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路上行走,若走到某个村庄中有宝物,则视为找到该村庄内的宝物,直

洛谷T1967 货车运输 Kruskal最大生成树&amp;&amp;倍增LCA

这题的题意是:对于每组x.y,求x到y路径上最小边权的最大值.于是可以使用最大生成树,因为最大生成树满足性质:生成树中最小边权最大,且任意两点间路径上最小边权最大.有了树之后,要求路径,那就要考虑LCA.首先,这题可以树剖,但是我太懒了,于是写了倍增233具体搞法:Kruskal跑出最大生成树,然后在树上倍增LCA,处理出2个数组:fa[][]和minv[][]:fa[][]表示第2^k个父亲是谁,minv[][]表示当前节点到其第2^k个父亲的路径上的最小边权.对于每次查询,在求LCA的同时,

HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow, and Blue are in war. The map of battlefield is a tree, which means that there are N nodes and (N – 1) edges that connect all the nodes. Each country

两种lca的求法:树上倍增,tarjan

第一种:树上倍增 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.继续用第一步的二进