1. 程式人生 > 其它 >區間修改主席樹

區間修改主席樹

逆十字巨巨的程式碼
儲存一下

#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;
}