• [bzoj3224]Tyvj 1728 普通平衡树


    来自FallDream的博客,未经允许,请勿转载,谢谢。


    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    n<=100000

    我怎么也没想到省选考了可持久化无旋Treap 妥妥爆10分。

    所以临时补一下无旋Treap 指针写起来挺舒服的

    #include<iostream>
    #include<cstdio>
    #define Size(x) (x?x->sz:0)
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    inline int Ran()
    {
        static int x=23333;
        x^=(x<<13);x^=(x>>17);x^=(x<<5);
        return x;
    }
    struct Treap
    {
        Treap *l,*r;
        int x,k,sz;
        Treap(){l=r=NULL;}
        Treap(int key){l=r=NULL;x=key;k=Ran();sz=1;}
        void update(){sz=Size(l)+Size(r)+1;}
    }*rt;
    typedef pair<Treap*,Treap*> D;
    Treap* Merge(Treap*x,Treap*y)
    {
        if(!x) return y;
        if(!y) return x;
        if(x->k<y->k) return x->r=Merge(x->r,y),x->update(),x;
        else return y->l=Merge(x,y->l),y->update(),y;
    }
    
    D Split(Treap*x,int Rk)
    {
        if(!x) return D(NULL,NULL);
        D b; 
        if(Size(x->l)>=Rk)
        {
            b=Split(x->l,Rk);
            x->l=b.second;
            x->update();
            b.second=x;
        }
        else
        {
            b=Split(x->r,Rk-Size(x->l)-1);
            x->r=b.first;
            x->update();
            b.first=x;
        }
        return b;
    }
    
    int Find(Treap*x,int v)
    {
        int sz=Size(x->l)+1;
        if(sz==v) return x->x;
        return sz<v?Find(x->r,v-sz):Find(x->l,v);
    }
    
    int GetRk(Treap*x,int v)
    {
        if(!x)return 0;    
        return v<=x->x?GetRk(x->l,v):GetRk(x->r,v)+Size(x->l)+1; 
    }
    void Insert(int v)
    {
        int rk=GetRk(rt,v);
        D a=Split(rt,rk);
        Treap*N=new Treap(v);
        N=Merge(a.first,N);
        rt=Merge(N,a.second);
    }
    
    void Delete(int v)
    {
        int Rk=GetRk(rt,v);
        D a=Split(rt,Rk);
        D b=Split(a.second,1);
        rt=Merge(a.first,b.second);
    }
    
    Treap* Ask_Before(Treap*x,int v)
    {
        if(!x) return NULL;
        Treap* a;
        if(x->x<v) return (a=Ask_Before(x->r,v))?a:x;
        else return Ask_Before(x->l,v);
    }
    
    Treap* Ask_After(Treap*x,int v)
    {
        if(!x) return NULL;
        Treap* a;
        if(x->x>v) return (a=Ask_After(x->l,v))?a:x;
        else return Ask_After(x->r,v);
    }
    
    int main()
    {    
        for(int n=read();n;--n)
        {
            int op=read(),x=read();
            if(op==1) Insert(x);
            if(op==2) Delete(x);
            if(op==3) printf("%d
    ",GetRk(rt,x)+1);
            if(op==4) printf("%d
    ",Find(rt,x));
            if(op==5) printf("%d
    ",Ask_Before(rt,x)->x);
            if(op==6) printf("%d
    ",Ask_After(rt,x)->x);
        }
        return 0;
    }
  • 相关阅读:
    学习进度——第十周
    梦断代码读后感03
    DFS入门——数的拆分
    DFS入门——素数环问题
    排列LCS问题
    洛谷P1436 棋盘分割 题解 二维区间DP
    洛谷P1241 括号序列 题解 栈
    《算法艺术与信息学竞赛》第1章 算法与数据结构 学习笔记
    洛谷P1563 玩具谜题(NOIP提高组2016 D1T1)题解 模拟
    洛谷P5022 旅行(NOIP提高组2018 D2T1)题解 贪心/去环
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj3224.html
Copyright © 2020-2023  润新知