题目链接:题目详情 - L2-012 关于堆的判断 (pintia.cn)
样例输入:
5 4
46 23 26 24 10
24 is the root
26 and 23 are siblings
46 is the parent of 23
23 is a child of 10
样例输出:
F
T
F
T
分析:这道题目其实是有点歧义的,因为他给出的x和y都是具体的数值,但是它并没有说明堆中的数是否可以重复,所以容易引起歧义,但由于他仅根据数值是否相同来判断关系,所以这里默认是不存在值相同的元素的。那么我们直接对小根堆进行模拟即可,每次都把当前元素放置末尾,然后对堆进行up操作,然后对排完序的每个位置的值进行一个映射,其中mp[i]记录值为i的元素的位置,我们是根据位置来判断节点之间关系的,剩下的就是一个字符串操作了,细节见代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=2e4+10;
int a[N];
map<int,int> mp;
void up(int x)//x是下标
{
while(x!=1&&a[x>>1]>a[x])
{
swap(a[x>>1],a[x]);
x>>=1;
}
}
int main()
{
int n,m;
cin>>n>>m;
int root=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
root=min(root,a[i]);
up(i);
}
for(int i=1;i<=n;i++)
mp[a[i]]=i;
int x,y;
string s;
for(int i=1;i<=m;i++)
{
cin>>x>>s;
if(s[0]=='a')
{
cin>>y>>s>>s;
if((mp[x]>>1)==(mp[y]>>1)) puts("T");
else puts("F");
}
else
{
cin>>s>>s;
if(s[0]=='r')
{
if(x==root) puts("T");
else puts("F");
}
else if(s[0]=='p')
{
cin>>s>>y;
if(mp[x]==(mp[y]>>1)) puts("T");
else puts("F");
}
else
{
cin>>s>>y;
if(mp[y]==(mp[x]>>1)) puts("T");
else puts("F");
}
}
}
return 0;
}