zoukankan      html  css  js  c++  java
  • BZOJ4825 单旋

    分析:一道水题,去年考场发现了特点但是不会splay维护挂了,然后现在我写了个treap。

    画一画图就可以解决这道题了,自己试一下。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 102000;
    int m,xxx;
    
    namespace Treap{
        struct spaly{int son[2],fa;}t[maxn];
        int sz[maxn],ch[maxn][2],num,SpalyRoot,Prs[maxn];
        int key[maxn],lazy[maxn],dep[maxn],data[maxn],root;
        void push_down(int now){
            dep[now] += lazy[now];
            lazy[ch[now][0]] += lazy[now]; lazy[ch[now][1]] += lazy[now];
            lazy[now] = 0;
        }
        int merge(int root1,int root2){
            if(!root1) return root2; if(!root2) return root1;
            if(lazy[root1]) push_down(root1); if(lazy[root2]) push_down(root2);
            if(key[root1] <= key[root2]){
                ch[root1][1] = merge(ch[root1][1],root2);
                Prs[ch[root1][1]] = root1;
                sz[root1] = sz[ch[root1][0]] + sz[ch[root1][1]] + 1;
                return root1;
            }else{
                ch[root2][0] = merge(root1,ch[root2][0]);
                Prs[ch[root2][0]] = root2;
                sz[root2] = sz[ch[root2][0]] + sz[ch[root2][1]] + 1;
                return root2;
            }
        }
        pair<int,int> split(int Node,int Len){
            if(Len == 0) return make_pair(0,Node);
            if(Node == 0) return make_pair(0,0);
            if(lazy[Node]) push_down(Node);
            if(sz[ch[Node][0]] >= Len){
                pair<int,int> Ans = split(ch[Node][0],Len);
                ch[Node][0] = Ans.second; Prs[Ans.second] = Node;
                Ans.second = Node; Prs[Ans.first] = 0;
                sz[Node] = sz[ch[Node][0]] + sz[ch[Node][1]] + 1;
                return Ans;
            }else{
                pair<int,int> Ans = split(ch[Node][1],Len-sz[ch[Node][0]]-1);
                ch[Node][1] = Ans.first; Prs[Ans.first] = Node;
                Ans.first = Node; Prs[Ans.second] = 0;
                sz[Node] = sz[ch[Node][0]] + sz[ch[Node][1]] + 1;
                return Ans;
            }
        }
        int get_rank(int Node,int Val){
            if(Node == 0) return 0;
            if(data[Node] > Val) return get_rank(ch[Node][0],Val);
            else return sz[ch[Node][0]]+1+get_rank(ch[Node][1],Val);
        }
        int get_Kth(int Node){
            stack<int> sta; int pts = Node;
            while(pts){sta.push(pts),pts = Prs[pts];}
            int Th = 0;
            while(!sta.empty()){
                int dat = sta.top();sta.pop();
                if(lazy[dat]) push_down(dat);
                if(!sta.empty()&&ch[dat][1] == sta.top()){
                    Th += sz[ch[dat][0]] + 1;
                }
            }
            Th += sz[ch[Node][0]] + 1;
            return Th;
        }
    }
    
    namespace operation{
        using namespace Treap;
        int Insert(int Val){
            if(root == 0){
                root++;sz[root]=1;key[root]=rand();data[root]=Val;dep[root]=1;
                num++;SpalyRoot++;return dep[root];
            }
            num++;sz[num] = 1;key[num] = rand();data[num] = Val;
            int rk = get_rank(root,Val);
            pair<int,int> nowp = split(root,rk);
            int rt = nowp.first,lt = nowp.second;
            while(ch[rt][1]) {if(lazy[rt])push_down(rt); rt = ch[rt][1];}
            while(ch[lt][0]) {if(lazy[lt])push_down(lt); lt = ch[lt][0];}
            if(lazy[rt]&&rt) push_down(rt); if(lazy[lt]&&lt) push_down(lt);
            if(!t[rt].son[1] && rt != 0){
                t[rt].son[1] = num;t[num].fa = rt;dep[num] = dep[rt]+1;
            }else{
                t[lt].son[0] = num;t[num].fa = lt;dep[num] = dep[lt]+1;
            }
            root = merge(merge(nowp.first,num),nowp.second);
            return dep[num];
        }
        int Spaly(int Kind){ // 0 min,1 max
            int nowp = root;
            while(ch[nowp][Kind]){
                if(lazy[nowp])push_down(nowp); nowp=ch[nowp][Kind];
            }
            if(nowp == SpalyRoot){return 1;}
            int Son = t[nowp].son[Kind^1],Father = t[nowp].fa;
            t[nowp].son[Kind^1] = SpalyRoot; t[SpalyRoot].fa = nowp;
            SpalyRoot = nowp;t[nowp].fa = 0;int finalans;
            int Len = get_Kth(Father);
            t[Father].son[Kind] = Son; t[Son].fa = Father;
            if(Kind == 0){
                pair<int,int> Ans = split(root,Len-1);
                pair<int,int> Cut = split(Ans.first,1);
                lazy[Ans.second]++;
                if(lazy[Cut.first]) push_down(Cut.first);
                finalans = dep[nowp]; dep[Cut.first] = 1;
                root = merge(merge(Cut.first,Cut.second),Ans.second);
            }else{
                pair<int,int> Ans = split(root,Len);
                pair<int,int> Cut = split(Ans.second,sz[Ans.second]-1);
                lazy[Ans.first]++;
                if(lazy[Cut.second]) push_down(Cut.second);
                finalans = dep[nowp];dep[Cut.second] = 1;
                root = merge(Ans.first,merge(Cut.first,Cut.second));
            }
            return finalans;
        }
        int Erase(int Kind){//0 min 1 max
            int finalans = Spaly(Kind);
            int nowp = root;
            while(ch[nowp][Kind]){
                if(lazy[nowp])push_down(nowp); nowp=ch[nowp][Kind];
            }
            SpalyRoot = t[nowp].son[Kind^1];
            t[SpalyRoot].fa = 0;t[nowp].son[Kind^1] = 0;
            pair<int,int> Les = split(root,get_Kth(nowp));
            pair<int,int> Spt = split(Les.first,get_Kth(nowp)-1);
            root = merge(Spt.first,Les.second);
            if(root != 0) lazy[root]--;
            return finalans;
        }
    }
    
    void work(){
        for(int i=1;i<=m;i++){xxx=i;
            int opt,x; scanf("%d",&opt);
            if(opt == 2 || opt == 3) printf("%d
    ",operation::Spaly(opt%2));
            else if(opt == 4 || opt == 5) printf("%d
    ",operation::Erase(opt%2));
            else {scanf("%d",&x);printf("%d
    ",operation::Insert(x));}
        }
    }
    
    int main(){
        srand(19260817);
        scanf("%d",&m);
        work();
        return 0;
    }
  • 相关阅读:
    AndroidStudio编译错误:Error: null value in entry: blameLogFolder=null
    Android中ViewPager实现滑动条及与Fragment结合的实例教程
    再说Android RecyclerView局部刷新那个坑
    【Android】图片切角,切指定的边。
    Android视频播放和横竖屏切换
    Android中3种全屏方法及3种去掉标题栏的方法
    Android 横竖屏切换
    android控件拖动,移动、解决父布局重绘时控件回到原点
    Android 自定义可拖拽View,界面渲染刷新后不会自动回到起始位置
    004 DOM01
  • 原文地址:https://www.cnblogs.com/1-1-1-1/p/8531108.html
Copyright © 2011-2022 走看看