LCA 倍增||树链剖分
方法1:倍增
1498ms
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <cstring>
- #include <cmath>
- using namespace std;
- typedef long long ll;
- const int N=5e5+;
- inline int read(){
- char c=getchar();int x=,f=;
- while(c<''||c>''){if(c=='-')f=-;c=getchar();}
- while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
- return x*f;
- }
- int n,q,root,a,b;
- struct edge{
- int v,ne;
- }e[N<<];
- int cnt=,h[N];
- inline void ins(int u,int v){
- cnt++;
- e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
- cnt++;
- e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
- }
- int fa[N][],deep[N],vis[N];
- void dfs(int u){
- vis[u]=;
- for(int j=;(<<j)<=deep[u];j++)
- fa[u][j]=fa[fa[u][j-]][j-];
- for(int i=h[u];i;i=e[i].ne){
- int v=e[i].v;
- if(vis[v]) continue;
- deep[v]=deep[u]+;
- fa[v][]=u;
- dfs(v);
- }
- }
- int lca(int x,int y){
- if(deep[x]<deep[y]) swap(x,y);
- int bin=deep[x]-deep[y];
- for(int i=;i<=;i++)
- if((<<i)&bin) x=fa[x][i];//,printf("x %d\n",i);
- for(int i=;i>=;i--)
- if(fa[x][i]!=fa[y][i]){
- x=fa[x][i];
- y=fa[y][i];
- }
- if(x==y) return x;
- else return fa[x][];
- }
- int main(int argc, const char * argv[]) {
- n=read();q=read();root=read();
- for(int i=;i<=n-;i++) a=read(),b=read(),ins(a,b);
- dfs(root);
- for(int i=;i<=q;i++){
- a=read();b=read();
- printf("%d\n",lca(a,b));
- }
- return ;
- }
方法2:树链剖分
1314ms
让链首深度大的走到重链的父节点直到在一条重链上,返回深度小的节点
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <cstring>
- #include <cmath>
- using namespace std;
- typedef long long ll;
- const int N=5e5+;
- inline int read(){
- char c=getchar();int x=,f=;
- while(c<''||c>''){if(c=='-')f=-;c=getchar();}
- while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
- return x*f;
- }
- int n,q,root,a,b;
- struct edge{
- int v,ne;
- }e[N<<];
- int cnt=,h[N];
- inline void ins(int u,int v){
- cnt++;
- e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
- cnt++;
- e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
- }
- int fa[N],deep[N],mx[N],size[N];
- void dfs(int u){
- size[u]++;
- for(int i=h[u];i;i=e[i].ne){
- int v=e[i].v;
- if(v==fa[u]) continue;
- fa[v]=u;deep[v]=deep[u]+;
- dfs(v);
- size[u]+=size[v];
- if(size[v]>size[mx[u]]) mx[u]=v;
- }
- }
- int tid[N],top[N],tot;
- void dfs(int u,int anc){
- if(!u) return;
- tid[u]=++tot;top[u]=anc;
- dfs(mx[u],anc);
- for(int i=h[u];i;i=e[i].ne){
- int v=e[i].v;
- if(v!=fa[u]&&v!=mx[u]) dfs(v,v);
- }
- }
- int lca(int x,int y){
- while(top[x]!=top[y]){
- if(deep[top[x]]<deep[top[y]]) swap(x,y);
- x=fa[top[x]];
- }
- if(deep[x]>deep[y]) swap(x,y);
- return x;
- }
- int main(int argc, const char * argv[]) {
- n=read();q=read();root=read();
- for(int i=;i<=n-;i++) a=read(),b=read(),ins(a,b);
- dfs(root);
- dfs(root,root);
- for(int i=;i<=q;i++){
- a=read();b=read();
- printf("%d\n",lca(a,b));
- }
- return ;
- }
LCA 倍增||树链剖分的更多相关文章
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- 【BZOJ3626】LCA(树链剖分,Link-Cut Tree)
[BZOJ3626]LCA(树链剖分,Link-Cut Tree) 题面 Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. ...
- 培训补坑(day8:树上倍增+树链剖分)
补坑补坑.. 其实挺不理解孙爷为什么把这两个东西放在一起讲..当时我学这一块数据结构都学了一周左右吧(超虚的) 也许孙爷以为我们是省队集训班... 好吧,虽然如此,我还是会认真写博客(保证初学者不会出 ...
- uva 12655 Trucks [LCA](树链剖分+MST)
The Subtle Balloons Company (SBC) is the main balloon provider for programming contests; it hashuge ...
- CF 191C Fools and Roads lca 或者 树链剖分
They say that Berland has exactly two problems, fools and roads. Besides, Berland has n cities, popu ...
- 从lca到树链剖分 bestcoder round#45 1003
bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或) ...
- P3379 【模板】最近公共祖先(LCA)(树链剖分)版
#include <bits/stdc++.h> #define read read() #define up(i,l,r) for(register int i = (l);i < ...
- 2018.09.16 bzoj3626: [LNOI2014]LCA(树链剖分)
传送门 树链剖分好题. 对于每个点维护一个值vi" role="presentation" style="position: relative;"&g ...
随机推荐
- DDD心得
使用DDD分层架构有哪些好处 帮你更集中的管理业务逻辑. 帮你降低各层间,以及各业务模块间的依赖关系. 帮你更方便的进行单元测试. 我的DDD分层架构使用经验 使用充血模型,将业务逻辑尽量放到领域实体 ...
- php基础知识
PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言[脚本在服务器上执行]. PHP 文件能够包含文本.HTML.CSS 以及 PHP 代码,在服务器上的执行结果以纯文本返回浏览器. php可以 ...
- 3、ASP.NET MVC入门到精通——Entity Framework增删改查
这里我接上讲Entity Framework入门.从网上下载Northwind数据库,新建一个控制台程序,然后重新添加一个ado.net实体数据模型. EF中操作数据库的"网关"( ...
- [原][C#][winForm]分级基金折溢价WinForm网络计算器
分级基金折溢价WinForm网络计算器 通过子/母基金代码,从 [ 东方财富网,天天基金网,新浪 ] 抓取分级基金的子母基金数据(代码,名称,净值,价格), 并计算出子基金(A基金,B基金)以及母基金 ...
- angular源码分析:$compile服务——指令的编写
这一期中,我不会分析源码,只是翻译一下"https://docs.angularjs.org/api/ng/service/$compile",当然不是逐字逐句翻译,讲解指令应该如 ...
- TypeScript的4种编译方式
1.手动编译 1.1.首先找到TypeScript的安装目录,我的在"C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0".
- javascript的函数
1.函数的声明 (1) function命令方式 function fn(){}; (2) 函数的表达式 采用变量赋值的方式,function命令后面不带有函数名.如果加上函数名,那么该函数名只在函数 ...
- SharePoint 自定义的列表页面中添加javascript的一个 For循环语句后,该页面就打不开了。
一个sharepoint 2013的普通的列表的自定义新建页面,我在其中新添加几行javascript代码后页面就打不开了.如图所示: 真是一言不合,友谊的页面说打不开就打不开啊.后来慢慢比对发现是因 ...
- IOS开发基础知识--碎片38
1:FCUUID获取设备标识的运用 a:作者 githun地址 https://github.com/fabiocaccamo/FCUUID 因为里面还用到作者的另外一个类UICKeyChainSto ...
- 安装gem所需知道的
1 在中国rubygem源被墙了,所以不管是gem install 还是bundle install都需要修改默认的源,淘宝和ruby-china都提供了源. gem source -r http:/ ...