• luogu p3369


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

    插入x数
    删除x数(若有多个相同的数,因只删除一个)
    查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
    查询排名为x的数
    求x的前驱(前驱定义为小于x,且最大的数)
    求x的后继(后继定义为大于x,且最小的数)
    输入输出格式
    输入格式:
    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1≤opt≤6 )

    输出格式:
    对于操作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≤100000
    2.每个数的数据范围: [-{10}^7, {10}^7]

    --------------------------------------------------------------------------------------

    刚学的,不用旋转的TREAP

    好写,主要就是split和merge两个操作。

    可以实现可持久化。

    可以实现区间操作。

    据说,比splay要慢

    --------------------------------------------------------------------------------------

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1e5+5;
      4 const int inf=1e9;
      5 struct node
      6 {
      7     int ch[2],val,rd,siz;
      8 }tr[maxn];
      9 int n,m,l,r;
     10 int tot,root;
     11 int newnode(int v)
     12 {
     13     ++tot;
     14     tr[tot].val=v;
     15     tr[tot].rd=rand();
     16     tr[tot].siz=1;
     17     tr[tot].ch[0]=tr[tot].ch[1]=0;
     18     return tot;
     19 }
     20 void update(int x)
     21 {
     22     tr[x].siz=tr[tr[x].ch[0]].siz+tr[tr[x].ch[1]].siz+1;
     23 }
     24 int merge(int a,int b)
     25 {
     26     if(a*b==0)return a+b;
     27     if(tr[a].rd<tr[b].rd)
     28     {
     29         tr[a].ch[1]=merge(tr[a].ch[1],b);
     30         update(a);
     31         return a;
     32     }
     33     else 
     34     {
     35         tr[b].ch[0]=merge(a,tr[b].ch[0]);
     36         update(b);
     37         return b;
     38     }
     39 }
     40 void split(int cur,int k,int &x,int &y)
     41 {
     42     if(!cur)x=y=0;
     43     else
     44     {
     45         if(tr[cur].val<=k)
     46         {
     47             x=cur;
     48             split(tr[cur].ch[1],k,tr[cur].ch[1],y);
     49         }
     50         else
     51         {
     52             y=cur;
     53             split(tr[cur].ch[0],k,x,tr[cur].ch[0]);
     54         }
     55         update(cur);
     56     }
     57 }
     58 void insert(int v)
     59 {
     60     int x,y;
     61     split(root,v,x,y);
     62     root=merge(merge(x,newnode(v)),y);
     63 }
     64 void del(int v)
     65 {
     66     int x,y,z;
     67     split(root,v,x,z);
     68     split(x,v-1,x,y);
     69     y=merge(tr[y].ch[0],tr[y].ch[1]);
     70     root=merge(merge(x,y),z);
     71 }
     72 void findrank(int v)
     73 {
     74     int x,y;
     75     split(root,v-1,x,y);
     76     printf("%d
    ",tr[x].siz+1);
     77     root=merge(x,y);
     78 }
     79 int kth(int now,int k)
     80 {
     81     int cur=now;
     82     while(cur)
     83     {
     84         if(tr[tr[cur].ch[0]].siz+1==k)return tr[cur].val;
     85         else if(tr[tr[cur].ch[0]].siz>=k)cur=tr[cur].ch[0];
     86         else 
     87         {
     88             k-=tr[tr[cur].ch[0]].siz+1;
     89             cur=tr[cur].ch[1];
     90         }
     91     }
     92     return -inf;
     93 }
     94 void pre(int v)
     95 {
     96     int x,y;
     97     split(root,v-1,x,y);
     98     printf("%d
    ",kth(x,tr[x].siz));
     99     root=merge(x,y);
    100 }
    101 void suc(int v)
    102 {
    103     int x,y;
    104     split(root,v,x,y);
    105     printf("%d
    ",kth(y,1));
    106     root=merge(x,y);
    107 }
    108 int main()
    109 {
    110     srand((unsigned)time(NULL));
    111     int n,op,v;
    112     scanf("%d",&n);
    113     while(n--)
    114     {
    115         scanf("%d%d",&op,&v);
    116         switch(op)
    117         {
    118             case 1:insert(v);break;
    119             case 2:del(v);break;
    120             case 3:findrank(v);break;
    121             case 4:printf("%d
    ",kth(root,v));break;
    122             case 5:pre(v);break;
    123             case 6:suc(v);break;
    124             default:break;
    125         }
    126     }    
    127     return 0;
    128 }
    View Code
  • 相关阅读:
    Discuz!X3.2 uc_server密码正确无法登录的解决方法
    手动添加uc应用及其 提示notelist表缺少appX字段的处理方法
    discuz 3 头像显示不成功
    用户名称修改的完美解决方法
    WEB服务器、应用程序服务器、HTTP服务器区别
    小议函数指针
    Difference Between objectForKey and valueForKey in NSDictionary
    valueforkey objectforkey区别,
    budle identifier,
    return,hiding 之前,
  • 原文地址:https://www.cnblogs.com/gryzy/p/10613064.html
Copyright © 2020-2023  润新知