ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

http://uoj.ac/problem/274

由于边权互不相同,只需用lct维护带加边的最大生成树

#include<bits/stdc++.h>
#define lc ch][0
#define rc ch][1
#define fa ch][2
#define rv ch][3
#define val ch][4
#define mv ch][5
#define len ch][6
#define sl ch][7
const int N=400007;
int ch[N][8],stk[N];
int _(){
    int x=0,c=getchar();
    while(c<48)c=getchar();
    while(c>47)x=x*10+c-48,c=getchar();
    return x;
}
int min(int a,int b){return a<b?a:b;}
int wc(int x){return x!=x[fa][lc];}
bool nrt(int x){return x==x[fa][lc]||x==x[fa][rc];}
void up(int x){
    int l=x[lc],r=x[rc];
    x[mv]=min(x[val],min(l[mv],r[mv]));
    x[sl]=x[len]+l[sl]+r[sl];
}
void _rv(int x){
    if(x)x[rv]^=1,std::swap(x[lc],x[rc]);
}
void dn(int x){
    if(x[rv]){
        x[rv]=0;
        _rv(x[lc]);
        _rv(x[rc]);
    }
}
void rot(int x){
    int f=x[fa],g=f[fa],d=wc(x);
    if(nrt(f))g[ch][wc(f)]=x;
    x[fa]=g;
    (f[ch][d]=x[ch][d^1])[fa]=f;
    (x[ch][d^1]=f)[fa]=x;
    up(f);
}
void sp(int x,int z=0){
    int stp=0;
    for(int a=x;nrt(stk[++stp]=a);a=a[fa]);
    for(;stp;dn(stk[stp--]));
    while(nrt(x)&&x[fa]!=z){
        int f=x[fa];
        if(nrt(f)&&f[fa]!=z)rot(wc(x)==wc(f)?f:x);
        rot(x);
    }
    up(x);
}
void acs(int x){
    int x0=x,y=0;
    for(;x;sp(x),x[rc]=y,up(y=x),x=x[fa]);
    sp(x0);
}
void mrt(int x){
    acs(x),_rv(x);
}
void get(int x,int y){
    mrt(x),acs(y),sp(x,y);
}
int n,m;
int main(){
    n=_();
    for(int i=0;i<=n;++i)i[val]=i[mv]=0x3f3f3f3f;
    for(m=_();m;--m){
        int o=_();
        if(o==60372){
            int id=_()+n+1,x=_()+1,y=_()+1,t=_(),l=_();
            get(x,y);
            id[val]=t,id[len]=l,up(id);
            if(x[fa]!=y)x[fa]=id,id[fa]=y;
            else if(x[rc][mv]<t){
                int z=x[rc],tg=x[rc][mv];
                for(;z[val]!=tg;dn(z),z=z[ch][z[lc][mv]!=tg]);
                sp(z);
                z[lc][fa]=z[rc][fa]=0,z[lc]=z[rc]=0,up(z);
                mrt(x),x[fa]=id,id[fa]=y;
            }
        }else if(o==68053){
            int x=_()+1,y=_()+1;
            printf("%d\n",x==y?0:(get(x,y),x[fa]!=y?-1:x[rc][sl]));
        }else{
            int id=_()+n+1,l=_();
            sp(id),id[len]=l,up(id);
        }
    }
    return 0;
}

 

posted on 2017-09-11 16:59  nul  阅读(129)  评论(0编辑  收藏  举报