传送门:

Treap 版本:

//OJ 1999
//by Cydiater
//2016.8.30
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <algorithm>
#include <string>
#include <iomanip>
using namespace std;
#define ll long long
#define up(i,j,n)    for(int i=j;i<=n;i++)
#define down(i,j,n)    for(int i=j;i>=n;i--)
const int MAXN=1e5+5;
const int oo=0x3f3f3f3f;
inline ll read(){
    char ch=getchar();ll x=0,f=1;
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int N,op,num,root=0,tol=0,ans=0;
struct node{
    int leftt,rightt,v,cnt,rnd,siz;
}t[MAXN];
namespace solution{
    void updata(int k){
        t[k].siz=t[t[k].leftt].siz+t[t[k].rightt].siz+t[k].cnt;
    }
    void lefturn(int &k){
        int tt=t[k].rightt;t[k].rightt=t[tt].leftt;t[tt].leftt=k;
        t[tt].siz=t[k].siz;updata(k);k=tt;
    }
    void righturn(int &k){
        int tt=t[k].leftt;t[k].leftt=t[tt].rightt;t[tt].rightt=k;
        t[tt].siz=t[k].siz;updata(k);k=tt;
    }
    void insert(int &k,int x){
        if(k==0){
            tol++;k=tol;t[k].siz=t[k].cnt=1;
            t[k].v=x;t[k].rnd=rand();
            return;
        }
        t[k].siz++;
        if(t[k].v==x)        t[k].cnt++;
        else if(x>t[k].v){
            insert(t[k].rightt,x);
            if(t[t[k].rightt].rnd<t[k].rnd)lefturn(k);
        }else{
            insert(t[k].leftt,x);
            if(t[t[k].leftt].rnd<t[k].rnd)righturn(k);
        }
    }
    void del(int &k,int x){
        if(k==0)    return;
        if(t[k].v==x){
            if(t[k].cnt>1){t[k].cnt--;t[k].siz--;return;}
            if(t[k].leftt*t[k].rightt==0)k=t[k].leftt+t[k].rightt;
            else if(t[t[k].leftt].rnd<t[t[k].rightt].rnd){
                righturn(k);del(k,x);
            }else{
                lefturn(k);del(k,x);
            }
        }else if(x>t[k].v){
            t[k].siz--;
            del(t[k].rightt,x);
        }else{
            t[k].siz--;
            del(t[k].leftt,x);
        }
    }
    int query_rank(int k,int x){
        if(k==0)return 0;
        if(t[k].v==x)        return t[t[k].leftt].siz+1;
        else if(x>t[k].v)    return t[t[k].leftt].siz+t[k].cnt+query_rank(t[k].rightt,x);
        else                 return query_rank(t[k].leftt,x);
    }
    int query_num(int k,int x){
        if(k==0)                                return 0;
        if(x<=t[t[k].leftt].siz)                return query_num(t[k].leftt,x);
        else if(x>t[t[k].leftt].siz+t[k].cnt)    return query_num(t[k].rightt,x-(t[t[k].leftt].siz+t[k].cnt));
        else                                     return t[k].v;
    }
    void query_pre(int k,int x){
        if(k==0)        return;
        if(t[k].v<x){
            ans=t[k].v;
            query_pre(t[k].rightt,x);
        }else query_pre(t[k].leftt,x);
    }
    void query_nxt(int k,int x){
        if(k==0)        return;
        if(t[k].v>x){
            ans=t[k].v;
            query_nxt(t[k].leftt,x);
        }else query_nxt(t[k].rightt,x);
    }
    void slove(){
        N=read();
        up(i,1,N){
            op=read();num=read();
            if(op==1)insert(root,num);
            if(op==2)del(root,num);
            if(op==3)printf("%d\n",query_rank(root,num));
            if(op==4)printf("%d\n",query_num(root,num));
            if(op==5){
                query_pre(root,num);
                printf("%d\n",ans);
            }
            if(op==6){
                query_nxt(root,num);
                printf("%d\n",ans);
            }
        }
    }
}
int main(){
    //freopen("input.in","r",stdin);
    using namespace solution;
    slove();
    return 0;
}

Splay 版本:

//BZOJ 3224
//by Cydiater
//2016.9.3
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
using namespace std;
#define ll long long
#define up(i,j,n)        for(int i=j;i<=n;i++)
#define down(i,j,n)        for(int i=j;i>=n;i--)
const int MAXN=1e6+5;
inline int read(){
    char ch=getchar();int x=0,f=1;
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int root=0,tol=0,N,op,num;
struct SplayTree{
    int son[2],siz,cnt,fa,v;
}t[MAXN];
namespace solution{
    inline int get(int x){return x==t[t[x].fa].son[1];}//get left or right son
    inline void clear(int x){
        t[x].son[0]=t[x].son[1]=t[x].cnt=t[x].v=t[x].fa=t[x].siz=0;
    }//reset node after deleted
    inline void updata(int x){//updata node after rotated
        if(x){
            t[x].siz=t[x].cnt;
            if(t[x].son[0])t[x].siz+=t[t[x].son[0]].siz;
            if(t[x].son[1])t[x].siz+=t[t[x].son[1]].siz;
        }
    }
    inline void rotate(int x){//rotate now node to root
        int old=t[x].fa,oldf=t[old].fa,which=get(x);
        t[old].son[which]=t[x].son[which^1];t[t[old].son[which]].fa=old;
        t[old].fa=x;t[x].son[which^1]=old;
        t[x].fa=oldf;
        if(oldf)t[oldf].son[t[oldf].son[1]==old]=x;
        updata(old);updata(x);
    }
    inline void splay(int x){
        for(int fa;(fa=t[x].fa);rotate(x))if(t[fa].fa)
        rotate((get(x)==get(fa)?fa:x));root=x;
    }
    inline void insert(int v){
        if(root==0){
            root=++tol;
            t[root].son[0]=t[root].son[1]=t[root].fa=0;
            t[root].v=v;t[root].cnt=t[root].siz=1;
            return;
        }
        int now=root,fa=0;
        while(1){
            if(t[now].v==v){
                t[now].cnt++;updata(now);updata(fa);
                splay(now);break;
            }
            fa=now;now=t[now].son[t[now].v<v];
            if(now==0){
                now=++tol;
                t[now].son[0]=t[now].son[1]=0;t[now].v=v;
                t[now].siz=t[now].cnt=1;t[now].fa=fa;
                t[fa].son[t[fa].v<v]=tol;
                updata(fa);
                splay(now);
                break;
            }
        }
    }
    inline int find(int v){
        int ans=0,now=root;
        while(1){
            if(v<t[now].v)now=t[now].son[0];
            else{
                ans+=(t[now].son[0]?t[t[now].son[0]].siz:0);
                if(v==t[now].v){splay(now);return ans+1;}
                ans+=t[now].cnt;
                now=t[now].son[1];
            }
        }
    }
    inline int get_rank(int x){
        int now=root;
        while(1){
            if(t[now].son[0]&&x<=t[t[now].son[0]].siz)now=t[now].son[0];
            else{
                int tmp=(t[now].son[0]?t[t[now].son[0]].siz:0)+t[now].cnt;
                if(x<=tmp)    return t[now].v;
                x-=tmp;now=t[now].son[1];
            }
        }
    }
    inline int pre(){
        int now=t[root].son[0];
        while(t[now].son[1])now=t[now].son[1];
        return now;
    }
    inline int nxt(){
        int now=t[root].son[1];
        while(t[now].son[0])now=t[now].son[0];
        return now;
    }
    inline void del(int x){
        int whatever=find(x);
        if(t[root].cnt>1){
            t[root].cnt--;
            t[root].siz--;
            return;
        }
        if(t[root].son[0]+t[root].son[1]==0){
            clear(root);root=0;
            return;
        }
        if(!t[root].son[0]){
            int oldroot=root;root=t[root].son[1];t[root].fa=0;
            clear(oldroot);return;
        }else if(!t[root].son[1]){
            int oldroot=root;root=t[root].son[0];t[root].fa=0;
            clear(oldroot);return;
        }
        int leftbig=pre(),oldroot=root;
        splay(leftbig);
        t[t[oldroot].son[1]].fa=root;
        t[root].son[1]=t[oldroot].son[1];
        clear(oldroot);
        updata(root);
        return;
    }
    void debug(int now){
        printf("now=%d t[now].son[0]=%d t[now].son[1]=%d t[now].siz=%d t[now].cnt=%d t[now].fa=%d t[now].v=%d\n",now,t[now].son[0],t[now].son[1],t[now].siz,t[now].cnt,t[now].fa,t[now].v);
        if(t[now].son[0])debug(t[now].son[0]);
        if(t[now].son[1])debug(t[now].son[1]);
    }
}
int main(){
    //freopen("input.in","r",stdin);
    using namespace solution;
    N=read();
    while(N--){
        op=read();num=read();
        if(op==1)insert(num);
        if(op==2)del(num);
        if(op==3)printf("%d\n",find(num));
        if(op==4)printf("%d\n",get_rank(num));
        if(op==5){
            insert(num);printf("%d\n",t[pre()].v);del(num);
        }
        if(op==6){
            insert(num);printf("%d\n",t[nxt()].v);del(num);
        }
        //debug(root);
        //puts("");
    }
    return 0;
}

关于Splay写的很好的一个博客:

传送门

BZOJ3224 普通平衡树的更多相关文章

  1. [BZOJ3224]普通平衡树(旋转treap,STL-vector)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 20328  Solved: 8979[Submit][St ...

  2. [bzoj3224]普通平衡树/3223文艺平衡树

    这是一道很普通的题.. 最近花了很多时间来想要去干什么,感觉自己还是太拿衣服 做这道题是因为偶尔看到了lavender的blog和她的bzoj早期AC记录,就被题目深深地吸引到了,原因有二: 自己sp ...

  3. BZOJ3224普通平衡树【Splay】

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 11751  Solved: 5013 Descriptio ...

  4. [TYVJ1728/BZOJ3224]普通平衡树-替罪羊树

    Problem 普通平衡树 Solution 本题是裸的二叉平衡树.有很多种方法可以实现.这里打的是替罪羊树模板. 此题极其恶心. 前驱后继模块需要利用到rank模块来换一种思路求. 很多细节的地方容 ...

  5. [转载]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)

    转载自ZZH大佬,原文:http://www.cnblogs.com/LadyLex/p/7182491.html 今天我们来学习一种新的数据结构:无旋treap.它和splay一样支持区间操作,和t ...

  6. [您有新的未分配科技点]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)

    今天我们来学习一种新的数据结构:无旋treap.它和splay一样支持区间操作,和treap一样简单易懂,同时还支持可持久化. 无旋treap的节点定义和treap一样,都要同时满足树性质和堆性质,我 ...

  7. bzoj3224 普通平衡树(c++vector)

    Tyvj 1728 普通平衡树 2014年8月23日6,4365 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有 ...

  8. BZOJ3224普通平衡树——非旋转treap

    题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...

  9. BZOJ3224普通平衡树——旋转treap

    题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...

  10. BZOJ3224普通平衡树

    洛谷题面链接 很早就过了,太久没打了,原本是在noip前用来练emacs的手感的. noip炸了,就滚回来更博客了(安排的计数任务刷不动,学不会容斥,打发时间...) 众所周知,splay是个好算法, ...

随机推荐

  1. fdisk分区硬盘并shell脚本自动化

    最近工作需要用到对硬盘进行shell脚本自动化分区和mount的操作,google了一些资料,下面做个总结. 如果硬盘没有进行分区(逻辑分区或者扩展分区,关于两者概念,自行google),我们将无法将 ...

  2. Redis Sentinel:集群Failover解决方案(转载)

    本文转载自:http://shift-alt-ctrl.iteye.com/blog/1884370 文中的配置例子,还有failover过程中触发的订阅事件具有很好的参考价值. Redis sent ...

  3. python环境搭建-Linux系统下python2.6.6升级python3.5.2步骤

    [root@template ~]# python -v # /usr/lib64/python2.6/encodings/utf_8.pyc matches /usr/lib64/python2.6 ...

  4. 运维mysql基础

    1 mysql简介 一般写某个东西先介绍一下,我就老生常谈的简单介绍下(摘自维基百科) https://zh.wikipedia.org/wiki/MySQL MySQL(官方发音为英语发音:/maɪ ...

  5. SpringMVC 部署项目静态资源文件访问问题

    问题:采用SpringMVC 部署项目后程序加载或用浏览器访问时出现类似的警告,2011-01-19 10:52:51,646 WARN [org.springframework.web.servle ...

  6. Windows命令 dos

    1.dos下运行netstat -na 查看本机开启的端口

  7. VirtualBox提示:错误,创建一个新任务失败,被召者解决办法

    被召者 RC: REGDB_E_CLASSNOTREG (0x80040154) 目前有两种解决办法: 解决方法一: 打开命令窗口(快捷键:窗口键+R,输入cmd点击确定) 输入cd D:\Progr ...

  8. Java Web项目中的经典代码抽取

    前言: 众所周知的,项目开发中做得最多的无非就是增删查改(CRUD)操作.自从国内Web项目开发渐渐盛行SSH框架之后,其开发开发流程也变得更加灵活:本文就项目开发中的业务层代码作个简单的抽取,供业内 ...

  9. python 列表与元组的操作简介

    上一篇:Python 序列通用操作介绍 列表 列表是可变的(mutable)--可以改变列表的内容,这不同于字符串和元组,字符串和元组都是不可变的.接下来讨论一下列表所提供的方法. list函数 可以 ...

  10. viewport ---移动端详解

    转自---http://www.cnblogs.com/2050/p/3877280.html 移动前端开发之viewport的深入理解 在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上 ...