zoukankan      html  css  js  c++  java
  • uoj#274. 【清华集训2016】温暖会指引我们前行

    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
    ",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;
    }
  • 相关阅读:
    Python实现二叉树的遍历
    Selenium模拟浏览器初识
    sklearn中的随机森林
    scrapy爬虫事件以及数据保存为txt,json,mysql
    mac安装mysql及终端操作mysql与pycharm的数据库可视化
    爬虫框架scrapy的基本内容
    多进程实例——爬取百度贴吧
    Python多进程并发操作进程池Pool
    【转】数据库设计三大范式
    【转】栈和堆的区别
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7505794.html
Copyright © 2011-2022 走看看