由上篇博客的性质,多个点的LCA等与dfs序最小的与最大的LCA。
不懂得可以看看我上篇bolg,独家证明。。
#include<bits/stdc++.h>
using namespace std;
const int M =1e5+7;
int head[M],cnt;
void init(){cnt=0,memset(head,-1,sizeof(head));}
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y){ee[++cnt].nxt=head[x],ee[cnt].to=y,head[x]=cnt;}
int st[M],ed[M],dep[M],lg[M*2],dp[M*2][20];
int euler[M*2],sz;
void dfs(int u,int fa)
{
euler[++sz]=u;
st[u]=sz;
// dep[u]=dep[fa]+1;
for(int i=head[u];i!=-1;i=ee[i].nxt)
{
int v=ee[i].to;
if(fa==v)continue;
dfs(v,u);
euler[++sz]=u;
}
ed[u]=sz;
}
void RMQ(int n)
{
lg[0]=-1;for(int i=1;i<=n;i++)lg[i]=lg[i>>1]+1;
for(int i=1;i<=n;i++)
dp[i][0]=st[euler[i]];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
{
dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
}
}
int query(int l,int r)
{
int k=lg[r-l+1];
return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
set<int>s;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
s.clear();
int n,m,x,u,v;
scanf("%d",&n);
init();sz=0;
for(int i=1;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
dfs(0,0);
RMQ(sz);
scanf("%d",&m);
while(m--)
{
char ss[3];
scanf("%s%d",ss,&x);
if(s.find(st[x])==s.end())s.insert(st[x]);
else s.erase(st[x]);
if(s.size()==0)
{
printf("%d\n",-1);
continue;
}
int l=*s.begin();
int r=*(--s.end());
// l=st[l],r=st[r];
if(l>r)swap(l,r);
// cout<<"---"<<l<<" "<<r<<endl;
printf("%d\n",euler[query(l,r)]);
}
}
return 0;
}