Trochę po czasie ale może komuś się przyda. Generalnie w zadaniu chodzi o to aby stwierdzać wartość wierzchołka na podstawie położenia go w drzewie, można to zrobić bawiąc się w znajdywanie lca i głębokości wierzchołka. Ponizej kod:
#include<bits/stdc++.h>
using namespace std;
#define st first
#define nd second
#define mp make_pair
typedef long long ll;
const int maxn = 2000005;
const int mn = 1000005;
const int d = 1000000; //stala do wierzcholkow w nowym drzewie
vector <int> g[maxn];
int l[mn], r[mn];
int ly[maxn], ry[maxn];
int now[maxn]; //przypisany numer wierzcholka w nowym drzewie
//lca
int pre[maxn];
int roz[maxn];
int p[maxn][21];
int depth[maxn];
bool odw[maxn];
int k=0, order=1, pot=1;
///nowy graf
void pol(int x, int y){ //polacz wierzcholki w nowym drzewie
if (r[x] != 0){
if (ry[y] == 0) ry[y] = r[x]+d;
now[r[x]] = ry[y];
pol(r[x], ry[y]);
}
if (l[x] != 0 && y != d+1){
if (ly[y] == 0) ly[y] = l[x]+d;
now[l[x]] = ly[y];
pol(l[x], ly[y]);
}
}
void lista_sasiedztwa(int x){
if (ry[x] != 0){
g[x].push_back(ry[x]);
lista_sasiedztwa(ry[x]);
}
if (ly[x] != 0){
g[x].push_back(ly[x]);
lista_sasiedztwa(ly[x]);
}
}
///lca
void dfs(int x){ //preorder, tablica przodkow
odw[x] = true;
roz[x] = 1;
pre[x] = order;
order++;
for (int i=0; i<g[x].size(); i++){
if (odw[g[x][i]] == false){
depth[g[x][i]] = depth[x]+1;
dfs(g[x][i]);
roz[x] += roz[g[x][i]];
p[g[x][i]][0] = x;
}
}
}
bool spr(int x, int y){
if (pre[y] >= pre[x] && pre[y] <= pre[x] + roz[x] - 1){
return true;
}
return false;
}
int lca(int a, int b){
if (spr(a, b) == true){
return a;
}
else if (spr(b, a) == true){
return b;
}
for(int i=k; i>=0; i--){
int a0 = p[a][i];
if (spr(a0, b) == false){
a = a0;
}
}
return p[a][0];
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n; cin >> n;
for (int i=1; i<=n; i++){
cin >> l[i] >> r[i];
}
//nowy graf
int x = 1;
while (true){
if (x == 0) break;
now[x] = d+1;
pol(x, d+1);
x = l[x];
}
lista_sasiedztwa(d+1);
//lca
while (pot <= n){
pot *= 2;
k += 1;
}
p[d+1][0] = d+1;
depth[d+1] = 1;
dfs(d+1);
for (int i=1; i<=k; i++){
for (int j=d+1; j<=d+n; j++){
p[j][i] = p[p[j][i-1]][i-1];
}
}
//zapytania
int q; cin >> q;
for (int i=0; i<q; i++){
int a, b; cin >> a >> b;
a = now[a];
b = now[b];
int lc = lca(a, b);
int lew = ly[lc];
int rig = ry[lc];
if (a == b){
cout << "TAK\n";
continue;
}
if (depth[a] != depth[b]){
if (depth[a] > depth[b]){
cout << "TAK\n";
}else{
cout << "NIE\n";
}
continue;
}
if ((pre[a] >= pre[rig] && pre[a] <= pre[rig]+roz[rig]-1) //a w prawym i b w lewym
&& (pre[b] >= pre[lew] && pre[b] <= pre[lew]+roz[lew]-1)){
cout << "TAK\n";
}
else if (b == lc){ //b == lc => a jest w poddrzewie b
cout << "TAK\n";
}
else{
cout << "NIE\n";
}
}
}
/*
5
2 5
0 3
0 4
0 0
0 0
12
2 10
3 7
0 4
0 5
0 6
0 0
0 8
9 0
0 0
0 11
0 12
0 0
5
0 2
3 4
0 0
5 0
0 0
*/