zoukankan      html  css  js  c++  java
  • LOJ104 普通平衡树

    题目描述

    这是一道模板题。

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

    1. 插入  x 数;
    2. 删除  x 数(若有多个相同的数,因只删除一个);
    3. 查询  x 数的排名(若有多个相同的数,因输出最小的排名);
    4. 查询排名为 x 的数;
    5. 求 x 的前趋(前趋定义为小于 x,且最大的数);
    6. 求 x 的后继(后继定义为大于 x,且最小的数)。

    输入格式

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

    输出格式

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

    样例

    样例输入

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

    样例输出

    106465
    84185
    492737
    

    数据范围与提示

     1<=n<=105,-107<=x<=107
     ___________________________________________________________________________
     
    fhq_treap模板
    ___________________________________________________________________________
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1e5+10;
      4 struct node
      5 {
      6     int val,lc,rc,siz,rd;
      7 }tr[maxn];
      8 int cnt,root,n;
      9 int newnode(int v)
     10 {
     11     ++cnt;
     12     tr[cnt].val=v;
     13     tr[cnt].siz=1;
     14     tr[cnt].rd=rand();
     15     tr[cnt].lc=tr[cnt].rc=0;
     16     return cnt;
     17 }
     18 void update(int cur)
     19 {
     20     tr[cur].siz=tr[tr[cur].lc].siz+tr[tr[cur].rc].siz+1;
     21 }
     22 int merge(int x,int y)
     23 {
     24     if(x*y==0)return x+y;
     25     if(tr[x].rd<tr[y].rd)
     26     {
     27         tr[x].rc=merge(tr[x].rc,y);
     28         update(x);
     29         return x;
     30     }
     31     else
     32     {
     33         tr[y].lc=merge(x,tr[y].lc);
     34         update(y);
     35         return y;
     36     }
     37 }
     38 void split(int cur,int v,int &x,int &y)
     39 {
     40     if(!cur)x=y=0;
     41     else
     42     {
     43         if(tr[tr[cur].lc].siz+1<=v)
     44         {
     45             x=cur;
     46             split(tr[cur].rc,v-tr[tr[cur].lc].siz-1,tr[cur].rc,y);
     47             update(cur);
     48         }
     49         else
     50         {
     51             y=cur;
     52             split(tr[cur].lc,v,x,tr[cur].lc);
     53             update(cur);
     54         }
     55     }
     56 }
     57 void splitv(int cur,int v,int &x,int &y)
     58 {
     59     if(!cur)x=y=0;
     60     else
     61     {
     62         if(tr[cur].val<=v)
     63         {
     64             x=cur;
     65             splitv(tr[cur].rc,v,tr[cur].rc,y);
     66             update(cur);
     67         }
     68         else
     69         {
     70             y=cur;
     71             splitv(tr[cur].lc,v,x,tr[cur].lc);
     72             update(cur);
     73         }
     74     }
     75 }
     76 void insert(int v)
     77 {
     78     int x,y;
     79     splitv(root,v,x,y);
     80     root=merge(merge(x,newnode(v)),y);
     81 }
     82 void del(int v)
     83 {
     84     int x,y,z;
     85     splitv(root,v,x,z);
     86     splitv(x,v-1,x,y);
     87     y=merge(tr[y].lc,tr[y].rc);
     88     root=merge(merge(x,y),z);
     89 }
     90 void find(int v)
     91 {
     92     int x,y;
     93     splitv(root, v-1,x,y);
     94     printf("%d
    ",tr[x].siz+1);
     95     root=merge(x,y);
     96 }
     97 void kth(int now,int v)
     98 {
     99     int cur=now;
    100     if(v>tr[now].siz || v<1)return ;
    101     while(cur)
    102     {
    103         if(tr[tr[cur].lc].siz+1==v)
    104         {
    105             printf("%d
    ",tr[cur].val);
    106             return ;
    107         }
    108         else if(tr[tr[cur].lc].siz >= v)cur=tr[cur].lc;
    109         else
    110         {
    111             v-=tr[tr[cur].lc].siz+1;
    112             cur=tr[cur].rc;
    113         }
    114     }
    115 }
    116 void pre(int v)
    117 {
    118     int x,y,z;
    119     splitv(root,v-1,x,y);
    120     kth(x,tr[x].siz);
    121     root=merge(x,y);
    122 }
    123 void next(int v)
    124 {
    125     int x,y,z;
    126     splitv(root,v,x,y);
    127     kth(y,1);
    128     root=merge(x,y);
    129 }
    130 int main()
    131 {
    132     scanf("%d",&n);
    133     for(int op,x,i=0;i<n;++i)
    134     {
    135         scanf("%d%d",&op,&x);
    136         if(op==1)insert(x);
    137         else if(op==2)del(x);
    138         else if(op==3)find(x);
    139         else if(op==4)kth(root,x);
    140         else if(op==5)pre(x);
    141         else next(x);
    142     }
    143     return 0;
    144 }
    View Code
  • 相关阅读:
    crm 4 注释与上传附件权限
    动态图片轮播
    PHP 连接 MSSQL
    php mssql 中文各种乱码
    百度地图逆地址解析
    Microsoft Visual C++ 2015 Redistributable(x64)
    服务器 vps 空间
    Python之路【第二篇】:Python基础(二)
    Python之路【第一篇】:Python简介和入门
    2016年会成为Java EE微服务年吗?
  • 原文地址:https://www.cnblogs.com/gryzy/p/10684015.html
Copyright © 2011-2022 走看看