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

    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
    这种treap只有两种操作:
    merge(root1,root2)和split(root,k)
    分别表示合并两颗treap和分割一个treap的前k个节点
    其他操作都通过这两个实现
    这样不用旋转,就可以持久化
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 struct Treap
      7 {
      8   Treap *l,*r;
      9   int val,size,lev;
     10 }S[200001],*pos=S,*root;
     11 int n;
     12 typedef pair<Treap*,Treap*> Droot;
     13 void NewNode(Treap* &r,int val)
     14 {
     15   r=++pos;
     16   r->val=val;
     17   r->lev=rand();
     18   r->size=1;
     19   r->l=r->r=0;
     20 }
     21 int getsize(Treap* x)
     22 {
     23   if (!x) return 0;
     24   else return x->size;
     25 }
     26 void updata(Treap* x)
     27 {
     28   x->size=1;
     29   if (x->l) x->size+=x->l->size;
     30   if (x->r) x->size+=x->r->size;
     31 }
     32 Treap *merge(Treap *A,Treap *B)
     33 {
     34   if (!A) return B;
     35   if (!B) return A;
     36   if (A->lev<B->lev)
     37     {
     38       A->r=merge(A->r,B);
     39       updata(A);
     40       return A;
     41     }
     42   else 
     43     {
     44       B->l=merge(A,B->l);
     45       updata(B);
     46       return B;
     47     }
     48 }
     49 Droot split(Treap *x,int k)
     50 {
     51   if (!x) return Droot(0,0);
     52   Droot y;
     53   if (getsize(x->l)>=k)
     54     {
     55       y=split(x->l,k);
     56       x->l=y.second;
     57       updata(x);
     58       y.second=x;
     59     }
     60   else 
     61     {
     62       y=split(x->r,k-getsize(x->l)-1);
     63       x->r=y.first;
     64       updata(x);
     65       y.first=x;
     66     }
     67   return y;
     68 }
     69 int findkth(int k)
     70 {
     71   Droot x=split(root,k-1);
     72   Droot y=split(x.second,1);
     73   Treap* ans=y.first;
     74   root=merge(merge(x.first,ans),y.second);
     75   if (ans==0) return 0;
     76   return ans->val;
     77 }
     78 int getkth(Treap* x,int val)
     79 {
     80   if (x==0) return 0;
     81   if (val<=x->val)
     82     return getkth(x->l,val);
     83   else return getkth(x->r,val)+getsize(x->l)+1;
     84 }
     85 void insert(int val)
     86 {
     87   int k=getkth(root,val);
     88   Droot x=split(root,k);
     89   Treap *a;
     90   NewNode(a,val);
     91   root=merge(merge(x.first,a),x.second);
     92 }
     93 int del(int val)
     94 {
     95   int k=getkth(root,val);
     96   Droot x=split(root,k);
     97   Droot y=split(x.second,1);
     98   Treap* ans=y.first;
     99   root=merge(x.first,y.second);
    100 }
    101 int main()
    102 {int opt,x;
    103   cin>>n;
    104   while (n--)
    105     {
    106       scanf("%d%d",&opt,&x);
    107       if (opt==1) 
    108     insert(x);
    109       else if (opt==2)
    110     del(x);
    111       else if (opt==3)
    112         printf("%d
    ",getkth(root,x)+1);
    113       else if (opt==4)
    114     printf("%d
    ",findkth(x));
    115       else if (opt==5)
    116     printf("%d
    ",findkth(getkth(root,x)));
    117       else if (opt==6)
    118     printf("%d
    ",findkth(getkth(root,x+1)+1));
    119     }
    120 }
  • 相关阅读:
    Linux常用命令及详细说明 — 结合工作(侧重性能监控,包括CPU、内存、IO、网络、磁盘等)
    navicat连接不上Linux服务器上的mysql的解决办法
    Git之rebase、merge和cherry pick的区别详解—面试常问
    阿里《JAVA实习生入职测试题—2019最新》之答案详解(连载一)
    技术语言框架学习方法论
    阿里《JAVA实习生入职测试题—2019最新》之答案详解(连载二)
    C# 文件/文件夹一般操作(File、Directory)
    Log4Net 使用及组合公共类
    VmWare 15 设置Centos7 共享文件夹及问题记录
    Centos 7 使用(Service iptables stop/start)关闭/打开防火墙 Failed to stop iptables.service: Unit iptables.service not loaded.
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7630765.html
Copyright © 2011-2022 走看看