思路:
果然是个很水的题,当时把自己考崩了,预感到凉了结果就真的凉了...当时也是zz,为啥老想着建树呢》????首先要判断是否出现过,肯定是map一下了.
其次就是找LCA,(考场傻逼到手刚LCA),因为这是一个BST树所以存在一个很重要的性质就是 左<根<右.
那么对于给定的两个值我们从根节点开始,往下走,总会走到一个节点分叉,那么这个点就是他们的最近公共祖先了.
那么最多1w个点,我们每次直接for一下就好了啊,找到 一个节点值 > u1 ,< u2的即可.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+5;
int n,m;
map<int,int>mp;
int a[maxn];
int main()
{
while(~scanf("%d %d",&m,&n))
{
mp.clear();
for(int i = 1;i <= n;++i)
{
scanf("%d",&a[i]);
mp[a[i]] = 1;
}
for(int i = 1;i <= m;++i)
{
int u,v;
scanf("%d %d",&u,&v);
if(mp[u] == 0 && mp[v] == 0)
printf("ERROR: %d and %d are not found.\n",u,v);
else if(mp[u] == 0 || mp[v] == 0)
printf("ERROR: %d is not found.\n",mp[u] == 0?u : v);
else
{
int f ;
for(int j = 1;j <= n;++j)
{
f = a[j];
if((f > v && f < u) || (f > u && f < v) || f == u || f == v)
break;
}
if(f == u || f == v)
printf("%d is an ancestor of %d.\n",f,u == f ? v : u);
else
printf("LCA of %d and %d is %d.\n",u,v,f);
}
}
}
return 0;
}
当然这个题建树也是可以做,先建树在跑LCA.由于1w个点,所以每次输入一个Insert,当是一条链就T了(-.-我就是这样T到死的)
这里来学一个新的建树方法,递归O(n)建立BST树.考虑到给定的为一个先序遍历,那么肯定是“根左右”,也就是第一个一定是根节点,那么怎么找到哪些是左子树哪些是右子树中的节点呢?还是利用BST的性质,左面都比根节点小右面都比根节点大,所以我们只需把当前区间的序列和根节点比较,直到找到一个大于他的就是左右子树间的分界线了,然后一直递归下去.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+5;
int a[maxn];
int n,m;
map<int,int>mp;
struct node
{
int val;
node *l;
node *r;
node()
{
l = r = nullptr;
}
};
node* build(int l,int r)
{
if(l > r) return nullptr;
if(l == r)
{
node *tmp = new node;
tmp -> val = a[l];
//cout << '-' << ' ' << tmp -> val << endl;
return tmp;
}
int i = l + 1;
while(i <= r && a[i] < a[l]) ++i;
node *tmp = new node;
tmp -> val = a[l];
//cout << '*' << ' ' << tmp -> val << endl;
tmp -> l = build(l + 1,i - 1);
tmp -> r = build(i,r);
return tmp;
}
int _find(node *root,int u,int v)
{
if(root == nullptr) return -1;
//cout << root -> val << endl;
if(root -> val == u || root -> val == v)
return root -> val;
if(root -> val > u && root -> val < v)
return root -> val;
if(root -> val > v)
return _find(root -> l,u,v);
if(root -> val < u)
return _find(root -> r,u,v);
}
int main()
{
while(~scanf("%d %d",&m,&n))
{
mp.clear();
for(int i = 1;i <= n;++i)
{
scanf("%d",&a[i]);
mp[a[i]] = 1;
}
node *root;
root = build(1,n);
// cout << root -> val<<endl;
for(int i = 1;i <= m;++i)
{
int u,v;
scanf("%d %d",&u,&v);
if(mp[u] == 0 && mp[v] == 0)
printf("ERROR: %d and %d are not found.\n",u,v);
else if(mp[u] == 0 || mp[v] == 0)
printf("ERROR: %d is not found.\n",mp[u] == 0 ? u : v);
else
{
int x1 = u,x2 = v;
if(x1 > x2) swap(x1,x2);
int f = _find(root,x1,x2);
if(f == u || f == v)
printf("%d is an ancestor of %d.\n",f,f == u ? v : u);
else
printf("LCA of %d and %d is %d.\n",u,v,f);
}
}
}
return 0;
}