hiho 17 最近公共祖先(三) 转换为区间最值查找 ST
来源:互联网 发布:代办申请淘宝直播 编辑:程序博客网 时间:2024/06/07 07:15
问题描述
原题链接
题目分析
之前的对这个问题有两种解法,解法一是对每次查询,都从根节点向下查询,复杂度为O(N*M), 第二种解法是先收集足够多的查询,然后深度搜索+并查集的方法找到每个结果,但是这种方法不能实时查询。下面我们将问题转换为区间查找问题,查询复杂度为O(1),预处理复杂度为O(N*logN)。
我从树的根节点开始进行深度优先搜索,每次经过某一个点——无论是从它的父亲节点进入这个点,还是从它的儿子节点返回这个点,都按顺序记录下来。这样,是不是就把一棵树转换成了一个数组?而找到树上两个节点的最近公共祖先,无非就是找到这两个节点最后一次出现在数组中的位置所囊括的一段区间中深度最小的那个点?”
#include <bits/stdc++.h>using namespace std;enum {maxn = 100000+5, maxnLog2= 17};vector<int> tree[maxn];int lastPos[maxn];int depth[maxn];int pre_cal[3*maxn][maxnLog2+2];int nodeNum;vector<string> names;unordered_map<string, int> nameToid;void dfs(int rt, int d){ depth[rt] = d; pre_cal[nodeNum++][0] = rt;// 进入该节点 for(int i=0; i< tree[rt].size(); i++) { dfs(tree[rt][i], d+1); pre_cal[nodeNum++][0] = rt; // 从子节点返回 } lastPos[rt] = nodeNum; pre_cal[nodeNum++][0] = rt;}int main(){ int n; scanf("%d", &n); string a, b; int A, B; for (int i=0; i< n; i++) { cin>>a>>b; if (!nameToid.count(a)) A = nameToid[a] = names.size(), names.push_back(a); else A = nameToid[a]; if (!nameToid.count(b)) B = nameToid[b] = names.size(), names.push_back(b); else B = nameToid[b]; tree[A].push_back(B); } nodeNum = 0; dfs(0, 0); for(int i=1, l=2; l+0<= nodeNum; l*=2, i++) { for (int j=0; j+l<= nodeNum; j++) { if (depth[pre_cal[j][i-1]] < depth[pre_cal[j+l/2][i-1]]) pre_cal[j][i] = pre_cal[j][i-1]; else pre_cal[j][i] = pre_cal[j+l/2][i-1]; } } int m; for(cin>>m; m; m--) { cin>>a>>b; A = lastPos[nameToid[a]]; B = lastPos[nameToid[b]]; if (A > B) swap(A, B);// 注意!。 int t = maxnLog2+2; int len = B+1-A; while((1<<t) > len) t--; int res; if (depth[pre_cal[A][t]] < depth[pre_cal[B+1 - (1<<t)][t]]) res = pre_cal[A][t]; else res = pre_cal[B+1-(1<<t)][t]; cout<<names[res]<<endl; } return 0;}
0 0
- hiho 17 最近公共祖先(三) 转换为区间最值查找 ST
- LCA和RMQ的一些事情(最近公共祖先与区间最值查询)
- HiHo #1068 : RMQ-ST算法 【ST求区间最值】
- hihocoder #1069 : 最近公共祖先·三(ST求LCA)
- hiho 15 最近公共子祖先(二)
- LCA(最近公共祖先算法)之在线st表法
- 最近公共祖先(LCA)问题-在线ST算法
- lca最近公共祖先(st表/倍增)
- 最近公共祖先LCA(Tarjan与DFS--ST倍增)
- ST表——【模板】最近公共祖先(LCA)
- 最近公共祖先(最简单算法)
- hiho第十三周 最近的公共祖先
- 【hiho一下】 最近公共祖先 一
- hiho一下 第十七周 最近公共祖先
- hiho#1062 : 最近公共祖先·一
- HIHO #1062 : 最近公共祖先·一
- Range Minimum Query and Lowest Common Ancestor 区间最值查询和最近公共祖先问题
- 查找最近公共祖先结点
- Xcode升级到7系列后 缺少 *.dylib库的解决方法
- acm中的“组合数”和“错排”
- Unity 获取指定资源目录下的所有文件
- jQuery 遍历
- 欢迎使用CSDN-markdown编辑器
- hiho 17 最近公共祖先(三) 转换为区间最值查找 ST
- Android:ContentProvider 随记2
- Sublime Text 3添加到右键菜单
- Android布局之LinerLayout点滴
- iOS 集成第三方微博登录功能
- Debug模式和Release模式
- c# 中执行js的问题
- 解决Unable to locate Spring NamespaceHandler for XML schema namespace
- 安卓手机拍照未显示到图库中参考办法