BZOJ4538: [Hnoi2016]网络

裸的树链剖分
永久化标记
数据结构居然1A感人

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#include<set>
#include<algorithm>
using namespace std;
multiset<int>All;
int rt;
char c;
inline void read(int &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
#define heap priority_queue<int>
struct Data
{
    heap Ad,De;
    int no;
    inline void Del(int A){if(A==Ad.top())Ad.pop();else De.push(A);}
    inline void Add(int A){if((!De.empty())&&A==De.top())De.pop();else Ad.push(A);}
    inline int da()
    {
        while(!De.empty())
        {
            if(De.top()<Ad.top())return Ad.top();
            Ad.pop(),De.pop();
        }
        return Ad.top();
    }
};
struct Seg
{
    int l,r;
    Data Rec;
}T[1000001];
int Dep[500001];
int HCB[500001],HCN[500001],HCP[500001],HCS[500001];
struct Chain
{
    int u;
    Chain *next;
}*Head[500001];
int F[500001];
int size[500001];
void DFS(int u,int f)
{
    size[u]++;
    Dep[u]=Dep[f]+1;
    HCS[u]=0;F[u]=f;
    for(Chain *tp=Head[u];tp;tp=tp->next)
        if(tp->u!=f)DFS(tp->u,u),size[u]+=size[tp->u],HCS[u]=(size[HCS[u]]<size[tp->u]?tp->u:HCS[u]);
}
int tot;
void DFS(int u,int f,int B)
{
    HCB[HCN[HCP[u]=++tot]=u]=B;
    if(HCS[u])DFS(HCS[u],u,B);
    for(Chain *tp=Head[u];tp;tp=tp->next)if(tp->u!=f&&tp->u!=HCS[u])DFS(tp->u,u,tot+1);
}
void Build(int place,int l,int r)
{
    T[place].l=l,T[place].r=r;
    T[place].Rec.Add(-1);
    if(l==r)
        return;
    int lc=place<<1,mid=l+r>>1,rc=lc|1;
    Build(lc,l,mid),Build(rc,mid+1,r);
}

void Add(int place,int l,int r,int delta)
{
   if(T[place].l>=l&&T[place].r<=r){T[place].Rec.Add(delta);return;}
   int lc=place<<1,rc=lc|1;
   if(T[lc].r>=l)Add(lc,l,r,delta);
   if(T[lc].r<r)Add(rc,l,r,delta);
}

void Del(int place,int l,int r,int delta)
{
    if(T[place].l>=l&&T[place].r<=r){T[place].Rec.Del(delta);return;}
   int lc=place<<1,rc=lc|1;
   if(T[lc].r>=l)Del(lc,l,r,delta);
   if(T[lc].r<r)Del(rc,l,r,delta);
}
int U[500001],V[500001],Da[500001];
int Query(int place,int l)
{
    if(T[place].l==T[place].r)return T[place].Rec.da();
    int lc=place<<1,rc=lc|1;
    if(l<=T[lc].r)return max(Query(lc,l),T[place].Rec.da());
    return max(Query(rc,l),T[place].Rec.da());
}
int Con;
struct Rt{int l,r;inline friend bool operator <(Rt a,Rt b){return a.l<b.l;}}L[200001];
int AddRuote(int l,int r){L[++Con]=(Rt){l,r};}
void MakeRuote(int no)
{
    Con=0;
    int u=U[no],v=V[no],deta=Da[no];
    while(HCB[u]^HCB[v])
    {
        if(Dep[HCN[HCB[v]]]>Dep[HCN[HCB[u]]])swap(u,v);
        AddRuote(HCB[u],HCP[u]);
        u=F[HCN[HCB[u]]];
    }
    if(HCP[u]>HCP[v])swap(u,v);
    AddRuote(HCP[u],HCP[v]);
}

void Add(int delta)
{
    sort(L+1,L+1+Con);
    if(L[1].l!=1)
    Add(1,1,L[1].l-1,delta);
    for(int i=2;i<=Con;i++)
        Add(1,L[i-1].r+1,L[i].l-1,delta);
    if(L[Con].r!=tot)Add(1,L[Con].r+1,tot,delta);
}
void Del(int delta)
{
    sort(L+1,L+1+Con);
    if(L[1].l!=1)
    Del(1,1,L[1].l-1,delta);
    for(int i=2;i<=Con;i++)
        Del(1,L[i-1].r+1,L[i].l-1,delta);
    if(L[Con].r!=tot)Del(1,L[Con].r+1,tot,delta);
}

inline int Query(int u)
{return Query(1,HCP[u]);}

inline void Add(int u,int v)
{
    Chain *tp=new Chain;
    tp->u=v,tp->next=Head[u],Head[u]=tp;
}



int n,m;
int main()
{
//  freopen("std.in","r",stdin);
//  freopen("self.out","w",stdout);
    read(n),read(m);
    int j,k;
    for(int i=1;i<n;i++)
    {
        read(j),read(k);
        Add(j,k),Add(k,j);
    }
    DFS(1,1);
    DFS(1,1,1);
    Build(1,1,tot);
    int tp;
    for(int i=1;i<=m;i++)
    {
        read(tp);
        if(tp==0)
        {
            read(U[i]),read(V[i]),read(Da[i]);
            MakeRuote(i);
            Add(Da[i]);
        }
        else if(tp==1)
        {
        read(tp);
        MakeRuote(tp);
        Del(Da[tp]);
        }
        else 
        {
        read(tp);
//      int tp=Query(tp);
        printf("%d\n",Query(tp));
        }

    }

    return 0;
}

你可能感兴趣的:(BZOJ4538: [Hnoi2016]网络)