zoukankan      html  css  js  c++  java
  • bzoj 3224 Tyvj 1728 普通平衡树 Treap

    Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 17187  Solved: 7501
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-2e9,2e9]
     
     
    题解:是用treap去维护,当然c++的STL也可以过(不知道为什么),
    这些都是treap的基本操作,复杂度是O(n log n)的。
     
      1 #include<cstring>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cstdio>
      6 
      7 #define ls tr[p].l
      8 #define rs tr[p].r
      9 #define N 100007
     10 #define inf 2000000010
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
     16     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 int n,sz,rt,ans;
     21 struct Node
     22 {
     23     int l,r,val,siz,rnd,ct;//记录左儿子,右儿子,点值,该子树大小,随机的值,该点值出现的次数。 
     24 }tr[N];//最多多少个节点,就开多少空间 
     25 
     26 inline int rand(){
     27     static int seed = 2333;
     28     return seed = (int)((((seed ^ 998244353) + 19260817ll) * 19890604ll) % 1000000007);
     29 }
     30 inline void update(int p)
     31 {
     32     tr[p].siz=tr[ls].siz+tr[rs].siz+tr[p].ct;
     33 }
     34 void lturn(int &p)
     35 {
     36     int t=tr[p].r;tr[p].r=tr[t].l;tr[t].l=p;
     37     tr[t].siz=tr[p].siz;update(p);p=t;
     38 }
     39 void rturn(int &p)
     40 {
     41     int t=tr[p].l;tr[p].l=tr[t].r;tr[t].r=p;
     42     tr[t].siz=tr[p].siz;update(p);p=t;
     43 }
     44 void ins(int &p,int x)
     45 {
     46     if (p==0)
     47     {
     48         p=++sz;
     49         tr[p].siz=tr[p].ct=1,tr[p].val=x,tr[p].rnd=rand();
     50         return;
     51     }
     52     tr[p].siz++;
     53     if (tr[p].val==x) tr[p].ct++;
     54     else if (x>tr[p].val)
     55     {
     56         ins(tr[p].r,x);
     57         if (tr[rs].rnd<tr[p].rnd) lturn(p);
     58     }else
     59     {
     60         ins(tr[p].l,x);
     61         if (tr[ls].rnd<tr[p].rnd) rturn(p);
     62     }
     63 }
     64 void del(int &p,int x)
     65 {
     66     if (p==0) return;
     67     if (tr[p].val==x)
     68     {
     69         if (tr[p].ct>1) tr[p].ct--,tr[p].siz--;//如果有多个直接减一即可。
     70         else
     71         {
     72             if (ls==0||rs==0) p=ls+rs;//单节点或者空的话直接儿子移上来或者删去即可。
     73             else if (tr[ls].rnd<tr[rs].rnd) rturn(p),del(p,x);
     74             else lturn(p),del(p,x); 
     75         }
     76     }
     77     else if (x>tr[p].val) tr[p].siz--,del(rs,x);
     78     else tr[p].siz--,del(ls,x);
     79 }
     80 int find_pm(int p,int x)
     81 {
     82     if (p==0) return 0;
     83     if (tr[p].val==x) return tr[ls].siz+1;
     84     if (x>tr[p].val) return tr[ls].siz+tr[p].ct+find_pm(rs,x);
     85     else return find_pm(ls,x);
     86 }
     87 int find_sz(int p,int x)
     88 {
     89     if (p==0) return 0;
     90     if (x<=tr[ls].siz) return find_sz(ls,x);
     91     x-=tr[ls].siz;
     92     if (x<=tr[p].ct) return tr[p].val;
     93     x-=tr[p].ct;
     94     return find_sz(rs,x);
     95 }
     96 int find_qq(int p,int x)
     97 {
     98     if (p==0) return -inf;
     99     if (tr[p].val<x) return max(tr[p].val,find_qq(rs,x));
    100     else if (tr[p].val>=x) return find_qq(ls,x);
    101 }
    102 int find_hj(int p,int x)
    103 {
    104     if (p==0) return inf;
    105     if (tr[p].val<=x) return find_hj(rs,x);
    106     else return min(tr[p].val,find_hj(ls,x));
    107 }
    108 int main()
    109 {
    110     n=read();
    111     for (int i=1;i<=n;i++)
    112     {
    113         int flag=read(),x=read();
    114         if (flag==1) ins(rt,x);
    115         if (flag==2) del(rt,x);
    116         if (flag==3) printf("%d
    ",find_pm(rt,x));//寻找x的排名
    117         if (flag==4) printf("%d
    ",find_sz(rt,x));//寻找排名为x的数字 
    118         if (flag==5) printf("%d
    ",find_qq(rt,x));
    119         if (flag==6) printf("%d
    ",find_hj(rt,x));
    120     }
    121 }
  • 相关阅读:
    zbb20171108 一台电脑启动多个 tomcat
    zbb20171101 oracle 启动 linux
    zbb20171017 svn Cleanup failed to process the following paths错误的解决
    zbb20171013 mysql服务重启 重启服务 重启mysql服务
    zbb20171013 mysql 远程连接 报错 1130-host ... is not allowed to connect to this MySql server
    zbb20171013 svnserver 修改默认端口
    zbb20171013 tomcat 设置访问ip地址直接访问项目
    zbb20171013 Windows 下端口占用 查询 以及结束进程的方法
    20171012 nginx 超时时间配置
    20171012 tomcat 超时时间配置
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7994382.html
Copyright © 2011-2022 走看看