点击查看代码
#include <bits/stdc++.h>
using namespace std;
vector<int>a[100005];
int dfn[100005],d[100005],s[100005],z[100005],nxt[100005],h[100005],fa[100005],tot;
struct t1
{
int l,r,va,sum,tag;
}t[400005];
void dfs1(int n1)
{
s[n1]=1;
for(int i=0;i<a[n1].size();i++)
{
if(a[n1][i]!=fa[n1])
{
d[a[n1][i]]=d[n1]+1;
fa[a[n1][i]]=n1;
dfs1(a[n1][i]);
s[n1]+=s[a[n1][i]];
if(s[a[n1][i]]>s[z[n1]])
{
z[n1]=a[n1][i];
}
}
}
}
void dfs2(int n1)
{
dfn[n1]=++tot;
if(z[n1])
{
nxt[n1]=z[n1];
h[z[n1]]=h[n1];
dfs2(z[n1]);
}
for(int i=0;i<a[n1].size();i++)
{
if(!dfn[a[n1][i]])
{
h[a[n1][i]]=a[n1][i];
dfs2(a[n1][i]);
}
}
}
void build(int p,int l,int r)
{
t[p].l=l;
t[p].r=r;
t[p].va=-1;
t[p].sum=0;
t[p].tag=0;
if(l==r)
{
return;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
}
int len(int p)
{
return t[p].r-t[p].l+1;
}
void pushdown(int p)
{
if(t[p].va>=0)
{
int va=t[p].va;
t[p].va=-1;
t[p*2].va=va;
t[p*2+1].va=va;
t[p*2].sum=len(p*2)*va;
t[p*2+1].sum=len(p*2+1)*va;
}
}
void change1(int p,int l,int r,int va)
{
if(l<=t[p].l&&r>=t[p].r)
{
t[p].va=va;
t[p].sum=(va*(t[p].r-t[p].l+1));
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)
{
change1(p*2,l,r,va);
}
if(r>mid)
{
change1(p*2+1,l,r,va);
}
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
void change2(int p,int l,int r,int va)
{
if(l<=t[p].l&&r>=t[p].r)
{
t[p].tag=va;
return;
}
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)
{
change2(p*2,l,r,va);
}
if(r>mid)
{
change2(p*2+1,l,r,va);
}
}
int ask1(int p,int l,int r)
{
if(l<=t[p].l&&r>=t[p].r)
{
return t[p].sum;
}
pushdown(p);
int va=0;
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)
{
va+=ask1(p*2,l,r);
}
if(r>mid)
{
va+=ask1(p*2+1,l,r);
}
return va;
}
int ask2(int p,int x)
{
if(t[p].l==t[p].r)
{
return t[p].tag;
}
int va=t[p].tag;
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid)
{
va=max(va,ask2(p*2,x));
}
else
{
va=max(va,ask2(p*2+1,x));
}
return va;
}
void Change(int u,int v,int i)
{
if(d[u]>d[v])
{
swap(u,v);
}
if(u!=h[u])
{
change1(1,dfn[u]-1,dfn[u]-1,0);
}
if(nxt[v])
{
change1(1,dfn[v],dfn[v],0);
}
if(u!=v)
{
change1(1,dfn[u],dfn[v]-1,1);
}
change2(1,dfn[u],dfn[v],i);
}
int Ask(int u,int v)
{
if(u!=v)
{
return ask1(1,min(dfn[u],dfn[v]),max(dfn[u],dfn[v])-1);
}
return 0;
}
int main()
{
freopen("edge.in","r",stdin);
freopen("edge.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
tot=0;
for(int i=1;i<=n;i++)
{
a[i].clear();
dfn[i]=0;
z[i]=0;
nxt[i]=0;
}
build(1,1,n);
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
a[u].push_back(v);
a[v].push_back(u);
}
d[1]=1;
dfs1(1);
h[1]=1;
dfs2(1);
for(int i=1;i<=m;i++)
{
int opt,u,v;
cin>>opt>>u>>v;
if(opt==1)
{
while(h[u]!=h[v])
{
if(d[h[u]]<d[h[v]])
{
swap(u,v);
}
Change(u,h[u],i);
u=fa[h[u]];
}
Change(u,v,i);
}
else
{
int ans=0;
while(h[u]!=h[v])
{
if(d[h[u]]<d[h[v]])
{
swap(u,v);
}
ans+=Ask(u,h[u]);
if(ask2(1,dfn[h[u]])==ask2(1,dfn[fa[h[u]]]))
{
ans+=(ask2(1,dfn[h[u]])!=0);
}
u=fa[h[u]];
}
ans+=Ask(u,v);
cout<<ans<<"\n";
}
}
}
return 0;
}