zoukankan      html  css  js  c++  java
  • bzoj千题计划218:bzoj2333: [SCOI2011]棘手的操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=2333

    上次那个是线段树,再发一个左偏树

    维护两种左偏树

    第一种是对每个联通块维护一个左偏树

    第二种是对所有第一种左偏树的根节点维护一个左偏树

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 300001
    
    /*void read(int &x)
    {
        x=0; int f=1; char c=getchar();
        while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); }
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }*/
    
    struct Leftist
    {
        int fa[N],lc[N],rc[N];
        int dis[N];
        int val[N],tag[N];
        
        int st[N];
        
        void addsingle(int x,int y)
        {
            if(!x) return;
            val[x]+=y;
            tag[x]+=y;
        }
        
        void down(int x)
        {
            if(!tag[x]) return;
            addsingle(lc[x],tag[x]);
            addsingle(rc[x],tag[x]);
            tag[x]=0;
        }
        
        void download(int x)
        {
            int top=0;
            for(int i=x;i;i=fa[i]) st[++top]=i;
            for(;top;--top) down(top);
        }
        
        int merge(int x,int y)
        {
            if(!x || !y) return x+y;
            if(val[x]<val[y]) swap(x,y);
            down(x);
            rc[x]=merge(rc[x],y);
            if(dis[lc[x]]<dis[rc[x]]) swap(lc[x],rc[x]);
            if(!rc[x]) dis[x]=0;
            else dis[x]=dis[rc[x]]+1;
            if(lc[x]) fa[lc[x]]=x;
            if(rc[x]) fa[rc[x]]=x;
            return x;
        }
        
        void del(int &root,int x)
        {
            int y=fa[x];
            bool k= rc[y]==x;
            x=merge(lc[x],rc[x]);
            fa[x]=y;
            if(!y) { root=x; return; }
            if(k) rc[y]=x;
            else lc[y]=x;
            if(dis[lc[y]]<dis[rc[y]]) swap(lc[y],rc[y]);
            x=rc[y];
            while(y && dis[y]!=dis[x]+1)
            {
                dis[y]=dis[x]+1;
                y=fa[y];
                if(dis[lc[y]]<dis[rc[y]]) swap(lc[y],rc[y]);
                x=rc[y];
            }
        }
        
        void push(int id,int &root,int x)
        {
            fa[id]=lc[id]=rc[id]=dis[id]=tag[id]=0;
            val[id]=x;
            root=merge(root,id);
        }
        
    }q,Q;
    
    int F[N];
    
    int find(int i)
    {
        return F[i]==i ? i : F[i]=find(F[i]);
    }
    
    int main()
    {
        int n,m,x,y;
        char s[4];
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&x);
            q.push(i,F[i],x);
            Q.push(i,F[0],x);
        }
        scanf("%d",&m);
        int add=0;
        while(m--)
        {
            scanf("%s",s);
            if(s[0]=='U')
            {
                scanf("%d",&x); 
                scanf("%d",&y);
                x=find(x);  y=find(y);
                if(x==y) continue;
                Q.del(F[0],x);
                Q.del(F[0],y);
                F[x]=F[y]=q.merge(x,y);
                x=F[x];
                Q.push(x,F[0],q.val[x]);
            }
            else if(s[0]=='A')
            {
                if(s[1]=='1')
                {
                     scanf("%d",&x);
                     scanf("%d",&y);
                     find(x);
                     Q.del(F[0],F[x]);
                     q.download(x);
                     int tmp=q.val[x];
                     q.del(F[x],x);
                     int z=F[x];
                     if(z)
                     {
                         F[z]=z;
                         q.push(x,F[z],tmp+y);
                         F[x]=F[z];
                     }
                     else q.push(x,F[x],tmp+y);
                     Q.push(F[x],F[0],q.val[F[x]]);
                }
                else if(s[1]=='2')
                {
                    scanf("%d",&x); 
                    scanf("%d",&y);
                    x=find(x);
                    Q.del(F[0],x);
                    q.addsingle(x,y);
                    Q.push(x,F[0],q.val[x]);
                }
                else 
                {
                    scanf("%d",&x);
                    add+=x;
                }
            }
            else
            {
                if(s[1]=='1')
                {
                    scanf("%d",&x);
                    q.download(x);
                    printf("%d
    ",q.val[x]+add);
                }
                else if(s[1]=='2')
                {
                    scanf("%d",&x);
                    x=find(x);
                    printf("%d
    ",q.val[x]+add);
                }
                else printf("%d
    ",Q.val[F[0]]+add);
            }
        }
    }
  • 相关阅读:
    使用ExcelMapper制作用于打印的矩阵
    八皇后问题-回溯法解
    HashMap-1.8 你看得懂的原理分析
    一生之敌
    必学十大经典排序算法,看这篇就够了(附完整代码/动图/优质文章)
    事务的四种隔离级别
    数据库的三范式
    ConcurrentHashMap底层实现原理和源码分析
    leetcode-160-相交链表(simple)
    JAVA中priorityqueue详解
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8391122.html
Copyright © 2011-2022 走看看