Luo Gu [P4319] changes in the road segment tree partition + LCT

Recently I learned about the tree line divide and conquer, feeling quite easy to use ...

If the normal maximum spanning tree, then dynamically maintained by LCT on the line, but there's a time limit of this dimension. 

So, we put into every edge node on a time axis of the tree line, and then write a revocable LCT like a ~ 

code: 

#include <bits/stdc++.h> 
#define RM 32766 
#define N 2000005   
#define ll long long 
#define setIO(s)    freopen(s".in","r",stdin) , freopen(s".out","w",stdout)   
using namespace std;            
namespace LCT 
{   
    #define lson t[x].ch[0] 
    #define rson t[x].ch[1] 
    struct node 
    {   
        ll sum;   
        int f,ch[2],rev,w,maxx,id;               
    }t[N];       
    int sta[N]; 
    inline int get(int x) { return t[t[x].f].ch[1]==x; }   
    inline int Irt(int x) { return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x); }        
    inline void mark(int x) 
    {
        if(!x)    return;    
        swap(lson,rson), t[x].rev^=1;   
    } 
    inline void pushdown(int x) 
    {
        if(x&&t[x].rev) 
        {
            if(lson)     mark(lson); 
            if(rson)     mark(rson); 
            t[x].rev=0;   
        }
    }     
    inline void pushup(int x) 
    {   
        t[x].id=x;  
        t[x].sum=t[x].w;  
        t[x].maxx=t[x].w;   
        if(lson)    
        {
            t[x].sum+=t[lson].sum;   
            if(t[lson].maxx>t[x].maxx) 
            {
                t[x].id=t[lson].id;  
                t[x].maxx=t[lson].maxx;  
            } 
        }
        if(rson)    
        {
            t[x].sum+=t[rson].sum; 
            if(t[rson].maxx>t[x].maxx) 
            {
                t[x].id=t[rson].id; 
                t[x].maxx=t[rson].maxx;  
            }       
        }
    }
    inline void rotate(int x) 
    {
        int old=t[x].f,fold=t[old].f,which=get(x);    
        if(!Irt(old))   t[fold].ch[t[fold].ch[1]==old]=x; 
        t[old].ch[which]=t[x].ch[which^1], t[t[old].ch[which]].f=old;       
        t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold;   
        pushup(old), pushup(x);   
    }
    inline void splay(int x) 
    {
        int u=x,v=0,fa;  
        for(sta[++v]=u;!Irt(u);u=t[u].f)       sta[++v]=t[u].f;   
        for(;v;--v)     pushdown(sta[v]);   
        for(u=t[u].f;(fa=t[x].f)!=u;rotate(x))  if(t[fa].f!=u)   rotate(get(fa)==get(x)?fa:x); 
    }
    inline void Access(int x) 
    { 
        for(int y=0;x;y=x,x=t[x].f)   splay(x),rson=y,pushup(x);  
    }
    inline void MakeRT(int x) 
    { 
        Access(x),splay(x),mark(x);  
    }
    inline void Link(int x,int y) 
    {
        MakeRT(y),t[y].f=x; 
    } 
    inline void split(int x,int y) 
    { 
        MakeRT(x),Access(y),splay(y); 
    }
    inline void cut(int x,int y) 
    {
        MakeRT(y),Access(x),splay(x);   
        t[x].ch[0]=t[y].f=0;  
        pushup(x);   
    }
    inline int findroot(int x) 
    {       
        for(Access(x),splay(x);lson;x=lson);  
        return x; 
    }
    #undef lson 
    #undef rson 
};   
#define lson now<<1 
#define rson now<<1|1  
int n; 
int tag[N];  
vector<int>G[N<<2];  
struct edge
{   
    int u,v,w;  
    edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){}   
}e[N];        
struct E 
{ 
    int u,op; 
    E(int u=0,int op=0):u(u),op(op){}  
};       
void Modify(int l,int r,int now,int L,int R,int id) 
{
    if(l>=L&&r<=R) 
    {   
        G[now].push_back(id);   
        return; 
    }  
    int mid=(l+r)>>1;   
    if(L<=mid)   Modify(l,mid,lson,L,R,id);   
    if(R>mid)    Modify(mid+1,r,rson,L,R,id);      
}      
void solve(int l,int r,int now,ll pre) 
{                        
    stack<E>S;  
    for(int i=0;i<G[now].size();++i) 
    {  
        int id=G[now][i];            
        int u=e[id].u,v=e[id].v,w=e[id].w;        
        int _new=id+n;   
        if(LCT::findroot(u)!=LCT::findroot(v)) 
        {      
            LCT::t[_new].w=w;    
            LCT::Link(u,_new);   
            LCT::Link(_new,v);    
            pre+=1ll*w;              
            S.push(E(_new,0));   
        }
        else 
        { 
            LCT::split(u,v);   
            if(LCT::t[v].maxx>w) 
            {    
                pre=pre-LCT::t[v].maxx+w;   
                int tmp=LCT::t[v].id;    
                LCT::cut(tmp,e[tmp-n].u); 
                LCT::cut(tmp,e[tmp-n].v);         
                LCT::t[_new].w=w;   
                LCT::Link(u,_new);   
                LCT::Link(_new,v);       
                S.push(E(tmp,1));   
                S.push(E(_new,0));       
            }
        }
    }     
    if(l==r)       printf("%lld\n",pre+1);   
    else 
    {           
        int mid=(l+r)>>1;   
        if(l<=mid)   solve(l,mid,lson,pre);    
        if(r>mid)    solve(mid+1,r,rson,pre);   
    }    
    while(!S.empty()) 
    {          
        E pp=S.top(); S.pop();  
        if(pp.op==0) 
        {  
            LCT::cut(pp.u,e[pp.u-n].u);  
            LCT::cut(pp.u,e[pp.u-n].v);  
        } 
        else
        {      
            LCT::t[pp.u].w=e[pp.u-n].w;  
            LCT::Link(pp.u,e[pp.u-n].u); 
            LCT::Link(pp.u,e[pp.u-n].v);  
        }
    }
}
#undef lson 
#undef rson  
int main()
{
    // setIO("input");
    int i,j,m;     
    scanf("%d",&n);     
    for(i=1;i<n;++i) 
    { 
        int u,v,w;                   
        scanf("%d%d%d",&u,&v,&w);            
        e[i]=edge(u,v,w);    
        Modify(1,RM,1,1,RM,i);     
    }
    scanf("%d",&m);    
    for(i=1;i<=m;++i) 
    {
        int u,v,w,l,r;    
        scanf("%d%d%d%d%d",&u,&v,&w,&l,&r), e[n+i-1]=edge(u,v,w), Modify(1,RM,1,l,r,n+i-1);   
    }           
    solve(1,RM,1,0ll);   
    return 0;
}

  

Guess you like

Origin www.cnblogs.com/guangheli/p/11941413.html