トピックリンク
https://pintia.cn/problem-sets/994805046380707840/problems/994805064676261888
アイデア
最初にシミュレーションによってヒープを実装し(ここではヒープの挿入のみを実装する必要があります)、次に4つのケースについて説明します。
- xはルートノードであり、ヒープの最初の要素がxであるかどうかを判断するだけで済みます。
- xはyの親ノードであり、 y >> 1 y>>1を判断するだけで済みます。Y>>>>1はxxに等しいxルートノードは1から始まるため、以下でも同じことが言えます。
- xはyの子ノードであり、 x >> 1 x>>1を判断するだけで済みます。バツ>>>>1はyyに等しいY
- xとyは兄弟であり、判断する必要があります(x >> 1)==(y >> 1)(x >> 1)==(y >> 1)(x>>>>1 )==(および>>>>1 )
子ノードが孫ノードと見なされるか(ここではカウントされない)、兄弟ノードが異父母であるか(ここでもカウントされない)など、ここで考えすぎる可能性が非常に高いことに注意してください。 。詳細については、コードを参照してください
コード
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000009
#define endl "\n"
#define PII pair<int,int>
const int N = 2e6+10;
int n,m,cnt,h[N],hp[N],ph[N];
int k,x,kk=0;
//ph记录的是第i次存入的下标
//hp记录的是下标为i是第几次存入的
//ph和hp是一个互逆的数组
void heap_swap(int a,int b){
//a、b都是下标
swap(ph[hp[a]],ph[hp[b]]);
swap(hp[a],hp[b]);
swap(h[a],h[b]);
}
void up(int u) {
//向上更新
while((u>>1) && h[u] < h[u>>1]) {
heap_swap(u,u >> 1);
u >>= 1;
}
}
void insert(int k){
cnt++;
kk++;//表示是第kk次插入的
h[cnt] = k;
ph[kk] = cnt,hp[cnt] = kk;
up(cnt);
}
map<int,int> st;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
string op;
cin>>n>>m;
for(int i = 1;i <= n; ++i){
cin>>k;
insert(k);
}
for(int i = 1;i <= n; ++i)
st[h[i]] = i;
while(m--){
string op;
int x,y;
cin>>x>>op;
bool ans;
if(op == "is"){
cin>>op;
if(op == "the") {
cin>>op;
if(op == "root") {
//x是根结点
if(h[1] == x) ans = true;
else ans = false;
} else {
//x是y的父结点
cin>>op>>y;
x = st[x],y = st[y];
if(x < y && (y>>1 == x)) ans = true;
else ans = false;
}
} else {
//x是y的一个子结点
cin>>op>>op>>y;
x = st[x],y = st[y];
if(x > y && (x>>1 == y)) ans = true;
else ans = false;
}
} else {
//x和y是兄弟结点
cin>>y;
getline(cin,op);
x = st[x],y = st[y];
if((x>>1) == (y>>1)) ans = true;
else ans = false;
}
if(ans) cout<<"T"<<endl;
else cout<<"F"<<endl;
}
return 0;
}