二叉搜索树上的LCA(最近公共祖先)
来源:互联网 发布:2017 unity3d开发语言 编辑:程序博客网 时间:2024/05/16 01:27
1017: Easy Tree Query
时间限制: 3 Sec 内存限制: 128 MB提交: 184 解决: 30
[提交][状态][讨论版]
题目描述
You are given a binary search tree with depth k, whose nodes are valued from 1 to (2k − 1) and then Q queries.
For each query, you are given p nodes. Find the root of a smallest subtree which contains all p nodes and print its value.
For each query, you are given p nodes. Find the root of a smallest subtree which contains all p nodes and print its value.
输入
The first line of input contains an integer T (T ≤ 100), the number of test cases. The first line of each test case contains two integers k (1 ≤ k ≤ 60) and Q (1 ≤ Q ≤ 10 4 ). In next Q lines, each line contains an integer p and then p integers — the values of nodes in this query. It is guaranteed that the total number of nodes given in each test case will not exceed 105.
输出
For each query, print a line contains the answer of that query.
样例输入
1
4 1
3 10 15 13
样例输出
12
#include<cstdio>#include<algorithm>#include<map>#include<cstring>#include<vector>#include<queue>#include<set>#include<map>#include<cstdlib>#include<iostream>using namespace std;typedef long long ll;#define mem(a,x) memset(a,x,sizeof a)const int maxn = (int)1e5 + 5;int T,k,q,p;ll ans, aa[maxn];// 基本的递归查找,二分查找,//如果mid 比y大,说明x,y的父节点在当前树的左子树。// 如果mid 比 x 小,说明x,y的父节点在当前树的右子树。//一旦找到mid 在 x y 中间,则直接返回midll get_lca(ll l,ll r, ll x ,ll y){ if(x > y) swap(x,y); ll mid = l + (r - l) / 2; if(y < mid) return get_lca(l,mid-1,x,y); if(x > mid) return get_lca(mid+1, r,x,y); return mid;}int main(){ scanf("%d",&T); while(T--){ scanf("%d %d",&k, &q); while(q--){ scanf("%d",&p); for(int i=1;i<=p;i++) scanf("%lld",&aa[i]); ans = aa[1]; ll n = (1ll << k)-1; for(int i=2;i<=p;i++) ans = get_lca(1,n,ans,aa[i]); printf("%lld\n",ans); } } return 0;}
比赛的时候想复杂了。通过将二叉搜索树上的值转化为二进制,然后找到了规律,每次都将当前的两个数转化为二进制,然后找到第一个不同的二进制位,先判断置为0可否,再判断了置为1可否。超时。
超时代码
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<iostream>using namespace std;typedef long long ll;const int maxn = 1e5 + 10;ll arr[maxn];int n=4,m;ll getone(ll pre, ll old){ if(pre == old) return pre; if(pre >old) swap(pre,old); ll ppre = pre; ll pold = old; vector<int>v1; vector<int>v2; while(pre){ v1.push_back(pre%2); pre>>=1; } while(old){ v2.push_back(old%2); old>>=1; } while(v1.size() < n) v1.push_back(0); while(v2.size() < n) v2.push_back(0); // reverse(v1.begin(),v1.end());// reverse(v2.begin(),v2.end()); ll ans = 0; int k = n-1;//// for(int i=0;i<v1.size();i++)// cout<<v1[i]<<" ";// cout<<endl;// for(int i=0;i<v2.size();i++)// cout<<v2[i]<<" ";// cout<<endl; for(int i=n-1;i>=0;i--){ if(v1[i] != v2[i]){ if(ans >= ppre && ans<= pold){ return ans; }else{ ll ans1 = ans + (1<<k); return ans1; } }else{ if(v1[i] == 1) ans += (1<<k); k--; } }}int main(){ //cout<<getone(2,4)<<endl; int T;scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); ll top = 1<<(n-1); int topn = n-1; while(m--){ int q;scanf("%d",&q); ll pre; for(int i=0;i<q;i++){ scanf("%lld",&arr[i]); if(i == 0) pre = arr[i]; else{ pre = getone(pre,arr[i]); } } printf("%lld\n",pre); } } return 0;}
0 0
- 二叉搜索树上的LCA(最近公共祖先)
- 二叉树的最近公共祖先LCA
- 二叉树-最近公共祖先(LCA)
- 二叉树最近公共祖先(LCA)
- 树上两点最近公共祖先LCA的倍增算法 poj1986
- 树上倍增求LCA(最近公共祖先)
- 最近公共祖先(LCA)之树上倍增法
- 二叉搜索树(BST)的最近公共祖先(LCA)问题(Lowest Common Ancestor of a Binary Tree)
- LCA(最近公共祖先)
- 【最近公共祖先(LCA)】
- 最近公共祖先(LCA)
- 最近公共祖先(LCA)
- LCA(最近公共祖先)
- LCA----【模板】最近公共祖先(LCA)
- 求解二叉树中两个节点的最近公共祖先(LCA)
- 设计算法查找二叉树的两个结点最近公共祖先(LCA)
- 最近公共祖先LCA
- 最近公共祖先(LCA)
- 如何计算分数的精确值
- 在Windows下安装gcc编译器
- 安卓中MVC模式的深度思索和实践(一)
- iOS播放GIF动画的几种方式
- 公司中Java使用Freemarker动态脚本查询Sql的坑
- 二叉搜索树上的LCA(最近公共祖先)
- iOS集成Weex
- Data Structures and algorithm analysis—1.1 What's the book about? (数据结构1.1—关于本书)
- oracle--查询练习
- TextView:超链接的样式与跳转
- 常用jar包
- linux下mysql的使用
- 滑动控件起飞的另一种方式
- 【Git】 git fetch和git pull的区别