zoukankan      html  css  js  c++  java
  • LOJ #558. 「Antileaf's Round」我们的 CPU 遭到攻击 LCT

    这个和 QTREE5 的套路是一样的,就是维护一个深度最深/浅的距离和,然后合并一下就好了. 

    code: 

    #include <map>
    #include <string> 
    #include <cstdio>    
    #include <cstring>  
    #include <algorithm>
    
    #define N 400008 
    #define ll long long 
    
    using namespace std; 
    
    namespace IO { 
        void setIO(string s) 
        {
            string in=s+".in"; 
            string out=s+".out"; 
            freopen(in.c_str(),"r",stdin); 
            // freopen(out.c_str(),"w",stdout);    
        }
    }; 
     
    namespace LCT {     
    
        #define lson t[x].ch[0] 
        #define rson t[x].ch[1] 
        #define get(x) (t[t[x].f].ch[1]==x)  
        #define Isr(x) (!(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x))    
    
        struct node { 
            int ch[2],rev,f,is_black;         
            ll son_size,son_dis;   
            ll size,ldis,rdis,dis,val;   
        }t[N];              
        int sta[N];  
    
        void Pushup(int x) 
        {     
            t[x].size=t[lson].size+t[rson].size+t[x].son_size;    
            t[x].dis=t[lson].dis+t[rson].dis+t[x].val;        
            t[x].ldis=t[lson].ldis+t[rson].ldis+t[x].son_dis+(t[x].son_size+t[rson].size)*(t[x].dis-t[rson].dis);
            t[x].rdis=t[rson].rdis+t[lson].rdis+t[x].son_dis+(t[x].son_size+t[lson].size)*(t[x].dis-t[lson].dis);
        }           
    
        void Mark_rev(int x) 
        { 
            t[x].rev^=1; 
            swap(lson,rson);
            swap(t[x].ldis,t[x].rdis);                 
        } 
    
        void Pushdown(int x) 
        {
            if(t[x].rev) 
            {
                if(lson)   Mark_rev(lson); 
                if(rson)   Mark_rev(rson);  
                t[x].rev^=1;   
            }
        } 
    
        void Rotate(int x) 
        {
            int old=t[x].f,fold=t[old].f,which=get(x);  
            if(!Isr(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); 
        }
    
        void Splay(int x) 
        {   
            int v=0,u=x,fa; 
            for(sta[++v]=u;!Isr(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);  
        }
    
        void Access(int x) 
        {   
            for(int y=0;x;y=x,x=t[x].f) 
            {
                Splay(x);    
                if(rson)   
                {         
                    t[x].son_size+=t[rson].size;   
                    t[x].son_dis+=t[rson].ldis;   
                }   
                if(y) 
                {
                    t[x].son_size-=t[y].size;    
                    t[x].son_dis-=t[y].ldis;   
                }
                rson=y;   
                Pushup(x); 
            }
        }   
    
        void Make_Root(int x) 
        {  
            Access(x),Splay(x),Mark_rev(x); 
        }      
    
        void Link_Edge(int x,int y) 
        {   
            Access(x),Splay(x); 
            Make_Root(y);   
            t[y].f=x;    
            t[x].son_size+=t[y].size;   
            t[x].son_dis+=t[y].ldis;   
        }
    
        void Cut_Edge(int x,int y) 
        {    
            Make_Root(x); 
            Access(y),Splay(y);    
            t[y].ch[0]=t[x].f=0;   
            Pushup(y);   
        }   
    
    }; 
    
    map<int,int>tr[N];   
    
    int main() 
    { 
        // IO::setIO("input");  
        using namespace LCT;   
        int i,j,n,m,q,tot;   
        scanf("%d%d%d",&n,&m,&q);       
        tot=n;   
        for(i=1;i<=m;++i) 
        {   
            int x,y,w; 
            scanf("%d%d%d",&x,&y,&w);             
            tr[x][y]=tr[y][x]=++tot;       
            LCT::t[tot].val=w;
            LCT::Link_Edge(x,tot);  
            LCT::Link_Edge(y,tot);   
        }          
        for(i=1;i<=q;++i) 
        { 
            char str[3];  
            scanf("%s",str);   
            if(str[0]=='L') 
            {  
                int x,y,w; 
                scanf("%d%d%d",&x,&y,&w);    
                tr[x][y]=tr[y][x]=++tot;    
                LCT::t[tot].val=w;   
                LCT::Link_Edge(x,tot); 
                LCT::Link_Edge(y,tot);  
            } 
            if(str[0]=='C') 
            {     
                int x,y,key=0; 
                scanf("%d%d",&x,&y);  
                key=tr[x][y];    
                LCT::Cut_Edge(x,key); 
                LCT::Cut_Edge(y,key);   
            } 
            if(str[0]=='F')
            {      
                int x; 
                scanf("%d",&x);    
                LCT::Access(x); 
                LCT::Splay(x);   
                LCT::t[x].is_black^=1;    
                if(LCT::t[x].is_black==0)  
                {
                    --t[x].son_size; 
                }
                else 
                {
                    ++t[x].son_size;   
                }
                LCT::Pushup(x); 
            } 
            if(str[0]=='Q') 
            {      
                int x; 
                scanf("%d",&x);        
                LCT::Make_Root(x);   
                Access(x);                      
                printf("%lld
    ",LCT::t[x].son_dis);   
            }
        }
        return 0; 
    }
    

      

  • 相关阅读:
    ASP.NET Core Web API 帮助页
    SQL SERVER 被锁住的表,以及解锁。
    关键字查找相关存储过程,函数和视图
    MsSql 生成数据文档
    WebApiTestClient 接口测试页
    sql日期
    为什么同样的Sql语句在SqlServer RDS 查询得到的和自己本机SqlServer 查询的不一样呢?
    VS 无法在web服务器上启动调试。您没有调试web服务器进程的权限
    ROS学习之创建工作空间
    QT学习之forward declaration of 'struct Ui::xxx';invalid use of incomplete struct "Ui::Widget"
  • 原文地址:https://www.cnblogs.com/guangheli/p/12102067.html
Copyright © 2011-2022 走看看