#include<cstdio>
#include<cstring>
#include<iostream>
#define ls u<<1,l,mid
#define rs u<<1|1,mid+1,r
#define maxn 500021
using namespace std;
int T,n,m;
struct Tree{
int lc[maxn*4],rc[maxn*4],flag[maxn*4],sum[maxn*4];
void push_up(int u){sum[u]=sum[u<<1]+sum[u<<1|1];}
void rot(int u){
sum[u]=rc[u]-lc[u]+1-sum[u];
flag[u]^=1;
}
void push_down(int u){
if(!flag[u])return;
rot(u<<1),rot(u<<1|1);
flag[u]=0;
}
int query(int u,int l,int r,int x,int y){
if(l==x&&r==y)return sum[u];
int mid=l+r>>1;
push_down(u);
if(x>mid)return query(rs,x,y);
else if(y<=mid)return query(ls,x,y);
else return query(ls,x,mid)+query(rs,mid+1,y);
}
void update(int u,int l,int r,int x,int y){
if(l==x&&r==y){
rot(u);
return;
}int mid=l+r>>1;
push_down(u);
if(x>mid)update(rs,x,y);
else if(y<=mid)update(ls,x,y);
else update(ls,x,mid),update(rs,mid+1,y);
push_up(u);
}
void build(int u,int l,int r){
lc[u]=l,rc[u]=r,sum[u]=flag[u]=0;
if(l==r)return;
int mid=l+r>>1;
build(ls),build(rs);
}
}W,L;
int top[maxn],fa[maxn],size[maxn],head[maxn],tot=1;
int h[maxn],son[maxn],dfn[maxn],cnt,cur[maxn];
struct edge{int v,next;}e[maxn*2];
void adde(int a,int b){e[tot].v=b,e[tot].next=head[a];head[a]=tot++;}
void dfs1(int u,int f){
fa[u]=f,h[u]=h[f]+1,size[u]=1,son[u]=0;
for(int v,i=head[u];i;i=e[i].next){
if((v=e[i].v)==f)continue;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>=size[son[u]])son[u]=v;
}
}
void dfs2(int u,int f,int tt){
dfn[u]=++cnt,cur[cnt]=u,top[u]=tt;
if(son[u])dfs2(son[u],u,tt);
for(int i=head[u],v;i;i=e[i].next){
if((v=e[i].v)==f||v==son[u])continue;
dfs2(v,u,v);
}
}
void change(int a,int b,int pos){
while(top[a]!=top[b]){
if(h[top[a]]>h[top[b]])swap(a,b);
if(!pos)W.update(1,1,n,dfn[top[b]],dfn[b]);
else{
if(top[b])W.update(1,1,n,dfn[top[b]],dfn[top[b]]);
if(son[b])W.update(1,1,n,dfn[son[b]],dfn[son[b]]);
L.update(1,1,n,dfn[top[b]],dfn[b]);
}
b=fa[top[b]];
}
if(h[a]>h[b])swap(a,b);
if(!pos){
if(a==b)return;
W.update(1,1,n,dfn[son[a]],dfn[b]);
}else{
if(son[b])W.update(1,1,n,dfn[son[b]],dfn[son[b]]);
W.update(1,1,n,dfn[a],dfn[a]);
L.update(1,1,n,dfn[a],dfn[b]);
}
}
int query(int a,int b){
int ans=0,x,y;
while(top[a]!=top[b]){
if(h[top[a]]>h[top[b]])swap(a,b);
x=top[a],y=top[b];
if(b!=top[b])ans+=W.query(1,1,n,dfn[son[y]],dfn[b]);
// int as=W.query(1,1,n,dfn[y],dfn[y]),ll=L.query(1,1,n,dfn[fa[y]],dfn[fa[y]]);
ans+=W.query(1,1,n,dfn[y],dfn[y])^L.query(1,1,n,dfn[fa[y]],dfn[fa[y]]);
b=fa[top[b]];
}
if(a==b)return ans;
if(h[a]>h[b])swap(a,b);
ans+=W.query(1,1,n,dfn[son[a]],dfn[b]);
return ans;
}
void solve(){
scanf("%d",&m);
int pos,a,b;
while(m--){
scanf("%d%d%d",&pos,&a,&b);
if(pos==3)printf("%d\n",query(a,b));
else change(a,b,pos-1);
}
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)head[i]=0;
tot=1,cnt=0;
for(int a,b,i=1;i<n;i++){
scanf("%d%d",&a,&b);
adde(a,b),adde(b,a);
}dfs1(1,0);
dfs2(1,0,1);
W.build(1,1,n),L.build(1,1,n);
solve();
}
return 0;
}
【hdu 4897】Little Devil I
最新推荐文章于 2018-09-02 21:24:57 发布