区间修改主席树
逆十字巨巨的代码
保存一下
#include<bits/stdc++.h>
using namespace std;
vector<int> v1[300010],v2[300010];//两张图
int T,n,x,y,dep[300010],rt[300010],tot,L[300010],R[300010],ans;//T,x,y
struct node{int ls,rs,ma,laz;}t[25000010];
void getdfn(int x,int fa=0)
{
L[x]=++tot;
for (int i=0,sz=v2[x].size(); i<sz; i++)
if (v2[x][i]!=fa) getdfn(v2[x][i],x);
R[x]=tot;
}
void pushdown(int i)
{
if (!t[i].ls) t[i].ls=++tot;
if (!t[i].rs) t[i].rs=++tot;
if (!t[i].laz) return;
t[t[i].ls].ma=t[t[i].ls].laz=t[i].laz;
t[t[i].rs].ma=t[t[i].rs].laz=t[i].laz;
t[i].laz=0;
}
int add(int i,int I,int l,int r,int ql,int qr,int v)//u,fa , l,r,ql,qr,v
{
t[i].ma=v;
if (l==ql&&r==qr)
{
int nw=v-t[I].ma;//res
t[i].ls=t[i].rs=0;//
t[i].laz=v;
return nw;
}
int mid=(l+r)>>1;
pushdown(I);
if (qr<=mid) return t[i].rs=t[I].rs,add(t[i].ls=++tot,t[I].ls,l,mid,ql,qr,v);
if (ql>mid) return t[i].ls=t[I].ls,add(t[i].rs=++tot,t[I].rs,mid+1,r,ql,qr,v);
return min(add(t[i].ls=++tot,t[I].ls,l,mid,ql,mid,v),add(t[i].rs=++tot,t[I].rs,mid+1,r,mid+1,qr,v));
}
void dfs(int x,int fa,int la)
{
dep[x]=dep[fa]+1,rt[x]=++tot;
la=min(la+1,add(rt[x],rt[fa],1,n,L[x],R[x],dep[x]));
ans=max(ans,la);
for (int i=0,sz=v1[x].size(); i<sz; i++)
if (v1[x][i]!=fa) dfs(v1[x][i],x,la);
}
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for (int i=1; i<=n; i++) v1[i].clear(),v2[i].clear();
for (int i=1; i<n; i++) scanf("%d%d",&x,&y),v1[x].push_back(y),v1[y].push_back(x);
for (int i=1; i<n; i++) scanf("%d%d",&x,&y),v2[x].push_back(y),v2[y].push_back(x);
tot=0,getdfn(1),tot=0,dep[0]=0,ans=0,dfs(1,0,10);
for (int i=1; i<=tot; i++) t[i].ls=t[i].rs=t[i].ma=t[i].laz=0;
printf("%d\n",ans);
}
return 0;
}