注意至少fa[N][log2(N)+1]
fa[i][j]:从i开始向上走
2
j
2^j
2j的大小即
i
+
2
j
i+2^j
i+2j<==>
i
+
2
j
−
1
+
2
j
−
1
i+2^{j-1}+2^{j-1}
i+2j−1+2j−1可得
fa[i][j]=fa[fa[i][j-1]][j-1]
循环应从log2[N]到0此时向上走由
2
p
>
(
2
p
−
1
)
2^p>(2^p-1)
2p>(2p−1)可知必定有一点刚好相等
传送门
#include <bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 4e4+10;
vector<int>g[N<<1];
int dep[N],fa[N][16];
void bfs(int x)
{
queue<int>q;
memset(dep,0x3f,sizeof dep);
dep[x]=1;
dep[0]=0;
q.push(x);
while(!q.empty()){
int temp=q.front();q.pop();
for(auto &t:g[temp]){
if(dep[t]>dep[temp]+1){
dep[t]=dep[temp]+1;
fa[t][0]=temp;
q.push(t);
for(int i=1;i<=15;i++)
fa[t][i]=fa[fa[t][i-1]][i-1];
}
}
}
}
int lca(int a,int b)
{
if(dep[a]<dep[b])swap(a,b);
for(int i=15;i>=0;i--)
if(dep[fa[a][i]]>=dep[b])
a=fa[a][i];
if(a==b)return a;
for(int i=15;i>=0;i--)
if(fa[a][i]!=fa[b][i])
a=fa[a][i],b=fa[b][i];
return fa[a][0];
}
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
int root;
for(int i=0,u,v;i<n;i++){
cin>>u>>v;
if(~v) g[u].push_back(v),g[v].push_back(u);
else root=u;
}
bfs(root);
int q;cin>>q;
while(q--){
int l,r;
cin>>l>>r;
int k=lca(l,r);
if(k==l)cout<<"1\n";
else if(k==r)cout<<"2\n";
else cout<<"0\n";
}
}