hihoCoder1232 Couple Trees LCA倍增算法+二分
2015-10-09 23:37
363 查看
题意:给你两颗树,节点编号都是1-n。根节点都为1,且父节点编号必大于子节点。有m次询问,每次给出两个坐标x,y,通过换算(与上一次询问结果有关),得到了两个节X,Y,
问这两个节点的在这两颗树中的最近公共祖先。
方法:求出每个点的倍增父节点,然后每次X,Y朝着倍增父节点尽量移动(尽量保证移的位置的节点大于另一个节点),如果不能保证,至少也得往前移一位。
问这两个节点的在这两颗树中的最近公共祖先。
方法:求出每个点的倍增父节点,然后每次X,Y朝着倍增父节点尽量移动(尽量保证移的位置的节点大于另一个节点),如果不能保证,至少也得往前移一位。
#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> #include <queue> #include <vector> using namespace std; const int N=1e5+5; vector<int>G ; queue<int>q; struct tree{ int p [21],dep ; void init(int n){ for(int i=1;i<=n;i++) for(int j=0;j<=20;j++) p[i][j]=i; } void BFS(int n){ q.push(1); dep[1]=1; while(!q.empty()){ int cur=q.front();q.pop(); for(int i=0;i<G[cur].size();i++){ dep[G[cur][i]]=dep[cur]+1; q.push(G[cur][i]); } for(int j=1;j<=20;j++){ p[cur][j]=p[p[cur][j-1]][j-1]; } } } void build(int n){ int u; for(int i=1;i<=n;i++)G[i].clear(); for(int i=2;i<=n;i++){ scanf("%d",&u); p[i][0]=u; G[u].push_back(i); } BFS(n); } }A,B; int Find(int *p,int n,int val){ int l=0,r=n,mid; int ret=0; while(l<=r){ mid=(l+r)>>1; if(p[mid]>=val){ ret=max(ret,mid); l=mid+1; } else r=mid-1; } return p[ret]; } int solve(int x,int y,int n){ if(x==y)return x; while(true){ if(x>y){ x=Find(A.p[x],20,y); } else{ y=Find(B.p[y],20,x); } if(x==y)return x; } } void work(){ int n,m; while(~scanf("%d%d",&n,&m)){ A.init(n);B.init(n); A.build(n);B.build(n); int pre=0; int x,y; while(m--){ scanf("%d%d",&x,&y); x=(x+pre)%n+1; y=(y+pre)%n+1; pre=solve(x,y,n); printf("%d %d %d\n",pre,A.dep[x]-A.dep[pre]+1,B.dep[y]-B.dep[pre]+1); } } } int main(){ //freopen("data.in","r",stdin); work(); return 0; }
相关文章推荐
- Makefile经典教程(掌握这些足够)
- 设计模式2-简单工厂模式
- JPEG与JPEG2000
- A*寻路算法
- EasyUI - Resizable 调整大小
- 《软件工程》第四次作业--目标软件(必应词典)
- ASP.NET本调试下配置Web.config识别json
- JSP页面间传递对象的方法与其特点
- android中的AIDL进程间通信
- C# 泛型理解之大白话
- Android学习之霓虹灯效果--所遇问题
- (mysql)触发器、事件、事务、函数
- Android学习实践:9.多选框CheckBox
- Hibernate缓存机制
- 【HDOJ】4183 Pahom on Water
- PDB文件
- Python学习笔记
- Centos 安装旧版php5.2
- 模块化利器: 一篇文章掌握RequireJS常用知识
- 字符编码细谈