rt,连第一个数据都过不了
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
const int badnumber=0;
int T,N,M;
struct SegmentTree{
int ls[maxn<<1],rs[maxn<<1],setv[maxn<<1];
int Lcolor[maxn<<1],Rcolor[maxn<<1],ans[maxn<<1];
int root,cnt;
void clear(){root=cnt=1;
memset(ls,0,sizeof(ls));memset(rs,0,sizeof(rs));
memset(Lcolor,0,sizeof(Lcolor));memset(Rcolor,0,sizeof(Rcolor));
memset(ans,0,sizeof(ans));memset(setv,0,sizeof(setv));ModifyRange(1,N,-114);
}SegmentTree(){clear();}
void pushup(int p){
Lcolor[p]=Lcolor[ls[p]];Rcolor[p]=Rcolor[rs[p]];
ans[p]=ans[ls[p]]+ans[rs[p]];
if(Rcolor[ls[p]]==Lcolor[rs[p]])++ans[p];
}
void pushdown(int p,int Len,int Ren){
if(!ls[p])ls[p]=++cnt;
if(!rs[p])rs[p]=++cnt;
if(setv[p]!=badnumber){
Lcolor[ls[p]]=Rcolor[ls[p]]=Lcolor[rs[p]]=Rcolor[rs[p]]=setv[p];
ans[ls[p]]=Len-1;ans[rs[p]]=Ren-1;
setv[ls[p]]=setv[rs[p]]=setv[p];
setv[p]=badnumber;}
}
void ModifyRange(int p,int L,int R,int ql,int qr,int xx){
if(ql<=L&&R<=qr){ans[p]=(R-L+1)-1;setv[p]=Lcolor[p]=Rcolor[p]=xx;return;}
int mid=(L+R)>>1;pushdown(p,mid-L+1,R-(mid+1)+1);
if(ql<=mid)ModifyRange(ls[p],L,mid,ql,qr,xx);
if(mid+1<=qr)ModifyRange(rs[p],mid+1,R,ql,qr,xx);
pushup(p);}void ModifyRange(int ql,int qr,int xx){
ModifyRange(root,1,N,ql,qr,xx);}
int QueryRange(int p,int L,int R,int ql,int qr,int &Lcrh,int &Rcrh){
if(ql<=L&&R<=qr){if(L==ql)Lcrh=Lcolor[p];if(R==qr)Rcrh=Rcolor[p];return ans[p];}
int mid=(L+R)>>1,ret=0;pushdown(p,mid-L+1,R-(mid+1)+1);
if(ql<=mid&&mid+1<=qr){
ret+=QueryRange(ls[p],L,mid,ql,qr,Lcrh,Rcrh);
ret+=QueryRange(rs[p],mid+1,R,ql,qr,Lcrh,Rcrh);
if(Rcolor[ls[p]]==Lcolor[rs[p]])++ret;
return ret;}
if(ql<=mid)ret+=QueryRange(ls[p],L,mid,ql,qr,Lcrh,Rcrh);
if(mid+1<=qr)ret+=QueryRange(rs[p],mid+1,R,ql,qr,Lcrh,Rcrh);
return ret;}int QueryRange(int ql,int qr,int LHQ,int RMJ){return QueryRange(root,1,N,ql,qr,LHQ,RMJ);}
int ASK(int ql,int qr){int _ddd,_dddd;return QueryRange(ql,qr,_ddd,_dddd);}
};
struct SLPF{
int val[maxn];
int head[maxn],nxt[maxn],to[maxn],cnt_edge;
int dep[maxn],Fa[maxn],Hd[maxn],Hson[maxn],id[maxn],size[maxn],dfn;
SegmentTree SEG;
void clear_data(){cnt_edge=dfn=0;
SEG.clear();
memset(head,0,sizeof(head));memset(to,0,sizeof(to));memset(nxt,0,sizeof(nxt));
memset(Hson,0,sizeof(Hson));memset(Hd,0,sizeof(Hd));memset(Fa,0,sizeof(Fa));
memset(size,0,sizeof(size));
}
void AddEdge(int u,int v){
nxt[++cnt_edge]=head[u];to[cnt_edge]=v;head[u]=cnt_edge;
nxt[++cnt_edge]=head[v];to[cnt_edge]=u;head[v]=cnt_edge;
}
void dfs1(int u,int v){
size[u]=1;dep[u]=dep[v]+1;Fa[u]=v;
for(int i=head[u];i;i=nxt[i]){if(to[i]==v)continue;
dfs1(to[i],u);size[u]+=size[to[i]];
if(size[to[i]]>size[Hson[u]])Hson[u]=to[i];
}
}
void dfs2(int u,int top){
id[u]=++dfn;Hd[u]=top;
if(!Hson[u])return;dfs2(Hson[u],top);
for(int i=head[u];i;i=nxt[i]){
if(to[i]==Fa[u]||to[i]==Hson[u])continue;
dfs2(to[i],to[i]);
}
}
void Read(){
scanf("%d%d",&N,&M);clear_data();
for(int i=1;i<N;i++){int a,b;scanf("%d%d",&a,&b);AddEdge(a,b);}
dfs1(1,0);dfs2(1,1);for(int i=1;i<=N;i++)SEG.ModifyRange(id[i],id[i],i);
}
void ModifyOnTree(int u,int v,int xx){
while(Hd[u]!=Hd[v]){
if(dep[Hd[u]]<dep[Hd[v]])swap(u,v);
SEG.ModifyRange(id[Hd[u]],id[u],xx);
u=Fa[Hd[u]];}
if(dep[u]<dep[v])swap(u,v);SEG.ModifyRange(id[v],id[u],xx);
}
int QueryOnTree(int u,int v){int ret=0,Ucolor=-1,Vcolor=-1;
while(Hd[u]!=Hd[v]){if(dep[Hd[u]]>dep[Hd[v]]){int LHQ,RMJ;
ret+=SEG.QueryRange(id[Hd[u]],id[u],LHQ,RMJ);
if(RMJ==Ucolor)++ret;Ucolor=LHQ;
u=Fa[Hd[u]];}else{int LHQ,RMJ;
ret+=SEG.QueryRange(id[Hd[v]],id[v],LHQ,RMJ);
if(RMJ==Vcolor)++ret;Vcolor=LHQ;
v=Fa[Hd[v]];}}int LHQ,RMJ;
if(dep[u]>dep[v]){
ret+=SEG.QueryRange(id[v],id[u],LHQ,RMJ);
if(RMJ==Ucolor)++ret;if(LHQ==Vcolor)++ret;
}else{
ret+=SEG.QueryRange(id[u],id[v],LHQ,RMJ);
if(RMJ==Vcolor)++ret;if(LHQ==Ucolor)++ret;
}
return ret;}
void Query(){int op,a,b;for(int QAQ__=1;QAQ__<=M;QAQ__++){scanf("%d%d%d",&op,&a,&b);
if(op==1){ModifyOnTree(a,b,N+QAQ__);}
else if(op==2){printf("%d\n",QueryOnTree(a,b));}
}}
void Solve(){scanf("%d",&T);while(T--)Read(),Query();}
}Tree;
int main(){Tree.Solve();return 0;}