• P3369 【模板】普通平衡树 Treap


     P3369 【模板】普通平衡树(Treap/SBT)

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

    1. 插入x数

    2. 删除x数(若有多个相同的数,因只删除一个)

    3. 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)

    4. 查询排名为x的数

    5. 求x的前驱(前驱定义为小于x,且最大的数)

    6. 求x的后继(后继定义为大于x,且最小的数)

    输入输出格式

    输入格式:

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1 leq opt leq 61opt6 )

    输出格式:

    对于操作3,4,5,6每行输出一个数,表示对应答案

    输入输出样例

    输入样例#1: 复制
    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598
    输出样例#1: 复制
    106465
    84185
    492737

    说明

    时空限制:1000ms,128M

    1.n的数据范围: n leq 100000n100000

    2.每个数的数据范围: [-{10}^7, {10}^7][107,107]

    来源:Tyvj1728 原名:普通平衡树

    在此鸣谢

    code

    treap 真是个好东西。。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<ctime>
      4 using namespace std;
      5 
      6 const int N = 200010;
      7 
      8 struct Data{
      9     int l,r,val,key,siz,cnt;
     10 }t[N];
     11 int Root,tn,ans;
     12 
     13 inline char nc() {
     14     static char buf[100000],*p1 = buf,*p2 = buf;
     15     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++;
     16 }
     17 inline int read() {
     18     int x = 0,f = 1;char ch=nc();
     19     for (; ch<'0'||ch>'9'; ch = nc()) 
     20         if (ch == '-') f = -1;
     21     for (; ch>='0'&&ch<='9'; ch = nc()) 
     22         x = x*10+ch-'0';
     23     return x * f;
     24 }
     25 
     26 inline void pushup(int x) {
     27     t[x].siz = t[t[x].l].siz + t[t[x].r].siz + t[x].cnt;
     28 }
     29 inline void leftturn(int &k) {
     30     int a = t[k].r;
     31     t[k].r = t[a].l;
     32     t[a].l = k;
     33     t[a].siz = t[k].siz;
     34     pushup(k);
     35     k = a;
     36 }
     37 inline void rightturn(int &k) {
     38     int a = t[k].l;
     39     t[k].l = t[a].r;
     40     t[a].r = k;
     41     t[a].siz = t[k].siz;
     42     pushup(k);
     43     k = a;
     44 }
     45 void Insert(int &k,int x) {
     46     if (k==0) {
     47         tn++;k = tn;
     48         t[k].siz = t[k].cnt = 1;
     49         t[k].val = x;t[k].key = rand();
     50         return ;
     51     }
     52     t[k].siz++;
     53     if (t[k].val==x) t[k].cnt ++;
     54     else if (x > t[k].val) {
     55         Insert(t[k].r,x);
     56         if (t[t[k].r].key < t[k].key) leftturn(k);
     57     }
     58     else {
     59         Insert(t[k].l,x);
     60         if (t[t[k].l].key < t[k].key) rightturn(k);
     61     }
     62 }
     63 void Delete(int &k,int x) {
     64     if (k==0) return ;
     65     if (t[k].val==x) {
     66         if (t[k].cnt > 1) {
     67             t[k].cnt--;t[k].siz--;return ;
     68         }
     69         if (t[k].l * t[k].r == 0) k = t[k].l + t[k].r;
     70         else if (t[t[k].l].key < t[t[k].r].key) {
     71             rightturn(k);Delete(k,x);
     72         }
     73         else {
     74             leftturn(k);Delete(k,x);
     75         }
     76     }
     77     else if (x > t[k].val) {
     78         t[k].siz--;Delete(t[k].r,x);
     79     }
     80     else {
     81         t[k].siz--;Delete(t[k].l,x);
     82     }
     83 }
     84 int getk(int k,int x) {
     85     if (k==0) return 0;
     86     if (t[k].val==x) return t[t[k].l].siz + 1;
     87     else if (x > t[k].val) 
     88         return t[t[k].l].siz + t[k].cnt + getk(t[k].r,x);
     89     else return getk(t[k].l,x);
     90 }
     91 int getkth(int k,int x) {
     92     if (k==0) return 0;
     93     if (x <= t[t[k].l].siz) return getkth(t[k].l,x);
     94     else if (x > t[t[k].l].siz + t[k].cnt) 
     95         return getkth(t[k].r,x-t[t[k].l].siz-t[k].cnt);
     96     else return t[k].val;
     97 }
     98 void getpre(int k,int x) {
     99     if (k==0) return ;
    100     if (t[k].val < x) ans = k,getpre(t[k].r,x);
    101     else getpre(t[k].l,x);
    102 }
    103 void getsuc(int k,int x) {
    104     if (k==0) return ;
    105     if (t[k].val > x) ans = k,getsuc(t[k].l,x);
    106     else getsuc(t[k].r,x);
    107 }
    108 
    109 int main() {
    110     int n = read();
    111     while (n--){
    112         int opt = read(),x = read();
    113         if (opt==1) Insert(Root,x);
    114         else if (opt==2) Delete(Root,x);
    115         else if (opt==3) printf("%d
    ",getk(Root,x));
    116         else if (opt==4) printf("%d
    ",getkth(Root,x));
    117         else if (opt==5) ans = 0,getpre(Root,x),printf("%d
    ",t[ans].val);
    118         else ans = 0,getsuc(Root,x),printf("%d
    ",t[ans].val);
    119     }    
    120     return 0;
    121 }

    更新后的treap

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<ctime>
      4 
      5 using namespace std;
      6 
      7 #define lson t[k].l
      8 #define rson t[k].r 
      9 const int N = 200010;
     10 
     11 struct Data{
     12     int l,r,val,key,siz,cnt;
     13 }t[N];
     14 int Root,tn,ans;
     15 
     16 inline char nc() {
     17     static char buf[100000],*p1 = buf,*p2 = buf;
     18     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++;
     19 }
     20 inline int read() {
     21     int x = 0,f = 1;char ch=nc();
     22     for (; ch<'0'||ch>'9'; ch = nc()) 
     23         if (ch == '-') f = -1;
     24     for (; ch>='0'&&ch<='9'; ch = nc()) 
     25         x = x*10+ch-'0';
     26     return x * f;
     27 }
     28 
     29 inline void pushup(int k) {
     30     t[k].siz = t[lson].siz + t[rson].siz + t[k].cnt;
     31 }
     32 inline void leftturn(int &k) {
     33     int a = rson;
     34     rson = t[a].l;
     35     t[a].l = k;
     36     t[a].siz = t[k].siz;
     37     pushup(k);
     38     k = a;
     39 }
     40 inline void rightturn(int &k) {
     41     int a = lson;
     42     lson = t[a].r;
     43     t[a].r = k;
     44     t[a].siz = t[k].siz;
     45     pushup(k);
     46     k = a;
     47 }
     48 void Insert(int &k,int x) {
     49     if (k==0) {
     50         tn++;k = tn;
     51         t[k].siz = t[k].cnt = 1;
     52         t[k].val = x;t[k].key = rand();
     53         return ;
     54     }
     55     t[k].siz++;
     56     if (t[k].val==x) t[k].cnt ++;
     57     else if (x > t[k].val) {
     58         Insert(rson,x);
     59         if (t[rson].key < t[k].key) leftturn(k);
     60     }
     61     else {
     62         Insert(lson,x);
     63         if (t[lson].key < t[k].key) rightturn(k);
     64     }
     65 }
     66 void Delete(int &k,int x) {
     67     if (k==0) return ;
     68     if (t[k].val==x) {
     69         if (t[k].cnt > 1) {
     70             t[k].cnt--;t[k].siz--;return ;
     71         }
     72         if (lson * rson == 0) k = lson + rson;
     73         else if (t[lson].key < t[rson].key) {
     74             rightturn(k);Delete(k,x);
     75         }
     76         else {
     77             leftturn(k);Delete(k,x);
     78         }
     79     }
     80     else if (x > t[k].val) {
     81         t[k].siz--;Delete(rson,x);
     82     }
     83     else {
     84         t[k].siz--;Delete(lson,x);
     85     }
     86 }
     87 int getk(int k,int x) {
     88     if (k==0) return 0;
     89     if (t[k].val==x) return t[lson].siz + 1;
     90     else if (x > t[k].val) 
     91         return t[lson].siz + t[k].cnt + getk(rson,x);
     92     else return getk(lson,x);
     93 }
     94 int getkth(int k,int x) {
     95     if (k==0) return 0;
     96     if (x <= t[lson].siz) return getkth(lson,x);
     97     else if (x > t[lson].siz + t[k].cnt) 
     98         return getkth(rson,x-t[lson].siz-t[k].cnt);
     99     else return t[k].val;
    100 }
    101 void getpre(int k,int x) {
    102     if (k==0) return ;
    103     if (t[k].val < x) ans = k,getpre(rson,x);
    104     else getpre(lson,x);
    105 }
    106 void getsuc(int k,int x) {
    107     if (k==0) return ;
    108     if (t[k].val > x) ans = k,getsuc(lson,x);
    109     else getsuc(rson,x);
    110 }
    111 
    112 int main() {
    113     int n = read();
    114     while (n--){
    115         int opt = read(),x = read();
    116         if (opt==1) Insert(Root,x);
    117         else if (opt==2) Delete(Root,x);
    118         else if (opt==3) printf("%d
    ",getk(Root,x));
    119         else if (opt==4) printf("%d
    ",getkth(Root,x));
    120         else if (opt==5) ans = 0,getpre(Root,x),printf("%d
    ",t[ans].val);
    121         else ans = 0,getsuc(Root,x),printf("%d
    ",t[ans].val);
    122     }    
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    JS中 try...catch...finally (转)
    Npm基本指令(转)
    常用Dos(转)
    理解Node.js异步非阻塞I/O与传统线性阻塞IO的区别(转)
    Java 连接 Access数据库方式
    感知器-从零开始学深度学习
    Oracle的SQL语句中如何处理‘&’符号
    (转)远程桌面超出最大连接数怎么办
    url中含有%
    (转)silverlight应用程序中未处理的错误代码:2104 类别:InitializeError
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8012483.html
Copyright © 2020-2023  润新知