bestcoders pog love szhIII
来源:互联网 发布:sql 子字符串 编辑:程序博客网 时间:2024/06/06 00:01
pog loves szh III
Accepts: 63
Submissions: 483
Time Limit: 12000/6000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
pog在与szh玩游戏,首先pog在纸上画了一棵有根树,这里我们定义1为这棵树的根,然后szh在这棵树中选了若干个点,想让pog帮忙找找这些点的最近公共祖先在哪里,一个点为S的最近公共祖先当且仅当以该点为根的子树包含S中的所有点,且该点深度最大。然而,这个问题是十分困难的,出于szh对pog的爱,他决定只找编号连续的点,即li ~ri 。
输入描述
若干组数据(不超过3 组n≥10000 或Q≥10000 )。每组数据第一行一个整数n(1≤n≤300000) ,表示树的节点个数。接下来n−1 行,每行两个数Ai,Bi ,表示存在一条边连接这两个节点。接下来一行一个数Q(1≤Q≤300000) ,表示有Q 组询问。接下来Q行每行两个数li,ri(1≤li≤ri≤n) ,表示询问编号为li ~ri 的点的最近公共祖先。
输出描述
对于每组的每个询问,输出一行,表示编号为li~ri的点的最近公共祖先的编号。
输入样例
51 21 33 44 551 22 33 43 51 5
输出样例
11331
Hint
珍爱生命,远离爆栈。
#include <iostream>#include <cstdio>#include <queue>#include <algorithm>#include <cstring>using namespace std;const int N = 400000 + 10;const int DEG = 20;int n, lca[N<<2];struct Edge{ int to, next;}edge[N*2]; // Undirectional edgeint head[N], tot;void init(){ tot = 0; memset(head, -1, sizeof(head));}void adde(int u, int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++;}int fa[N][DEG], deg[N];void BFS(int root) //预处理得到之后二分搜索所需的顶点信息{ queue<int> que; deg[root] = 0; fa[root][0] = root; que.push(root); while(!que.empty()) { int u = que.front(); que.pop(); for(int i=1; i<DEG; i++) fa[u][i] = fa[fa[u][i-1]][i-1]; for(int i=head[u]; i!=-1; i=edge[i].next) { int v = edge[i].to; if(v == fa[u][0]) continue; //判断该节点之前是否访问过 deg[v] = deg[u] + 1; fa[v][0] = u; que.push(v); } } cout<<endl;}int LCA(int u, int v)//二分搜索求出到达公共祖先所需的最少步数{ if(deg[u] > deg[v]) swap(u, v); int hu = deg[u], hv = deg[v]; int tu = u, tv = v; for(int det=hv-hu, i=0; det; det>>=1, i++) if(det&1) tv = fa[tv][i]; if(tu == tv) return tu; for(int i=DEG-1; i>=0; i--) if(fa[tu][i] != fa[tv][i]) { tu = fa[tu][i]; tv = fa[tv][i]; } return fa[tu][0];}#define root 1, n, 1#define lson L, mid, rt<<1#define rson mid+1, R, rt<<1|1#define lr rt<<1#define rr rt<<1|1void Up(int rt){ lca[rt] = LCA(lca[lr], lca[rr]);}void bulid(int L, int R, int rt){ if(L == R) { lca[rt] = L; return ; } int mid = (L+R)>>1; bulid(lson); bulid(rson); Up(rt);}int Query(int l, int r, int L, int R, int rt)//求出区间[l, r]的LCA{ if(l==L && r==R) return lca[rt]; int mid = (L+R)>>1; if(r <= mid) return Query(l, r, lson); else if(l>mid) return Query(l, r, rson); else return LCA(Query(l, mid, lson), Query(mid+1, r, rson));}int main(){ int n, q; while(~scanf("%d", &n)) { init(); int u, v; for(int i=0; i<n-1; i++) { scanf("%d%d", &u, &v); adde(u, v); adde(v, u); } BFS(1); bulid(root); scanf("%d", &q); for(int i=0; i<q; i++) { scanf("%d%d", &u, &v); printf("%d\n", Query(u, v, root)); } } return 0;}
1 0
- bestcoders pog love szhIII
- bestcoders
- Bestcoders
- Bestcoders
- BestCoders
- Bestcoders
- Bestcoders
- bestcoders Happy Birthday
- Bestcoders 51 div2 1001
- Bestcoders 57 1002
- Love
- LOVE
- love
- Love
- Love
- love
- love
- love
- 跨平台交互的检测方法及装置
- PCL库依赖第三方库的功能说明--摘录点云库PCL学习教程
- 希尔排序算法
- 找出数组中只出现一次的数字
- 不更改时区,会返回一个空的NSDate对象
- bestcoders pog love szhIII
- 基于局部保持投影(LPP)的人脸特征检测
- 安装JDK,配置环境变量
- 一种 IM 删除信息的恢复方法
- linux C++ 进程间共享内存以及临界区的实现
- 【Android Net】Volley实现(multipart/form-data)Post请求
- 整合ssh框架的具体步骤
- Python实例属性和类属性的区别
- Java serve_ client聊天之client端(合工大java实验四)by峰宇