zoukankan      html  css  js  c++  java
  • (treap)[bzoj3224][洛谷3369][cogs1829]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]

    Source

    平衡树

    STL用法练手题。。。(手动滑稽)
    这数据我给满分
    (感谢hzwer...)
     1 // It is made by XZZ
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 using namespace std;
     6 #define rep(a,b,c) for(rg int a=b;a<=c;a++)
     7 #define drep(a,b,c) for(rg int a=b;a>=c;a--)
     8 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
     9 #define il inline
    10 #define rg register
    11 #define vd void
    12 typedef long long ll;
    13 il int gi(){
    14     rg int x=0,f=1;rg char ch=getchar();
    15     while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
    16     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    17     return x*f;
    18 }
    19 vector<int>A;
    20 int main(){
    21     int n=gi(),opt,x;
    22     while(n--){
    23     opt=gi(),x=gi();
    24     if(opt==1)A.insert(upper_bound(A.begin(),A.end(),x),x);
    25     else if(opt==2)A.erase(lower_bound(A.begin(),A.end(),x));
    26     else if(opt==3)printf("%d
    ",lower_bound(A.begin(),A.end(),x)-A.begin()+1);
    27     else if(opt==4)printf("%d
    ",A[x-1]);
    28     else if(opt==5)printf("%d
    ",*(lower_bound(A.begin(),A.end(),x)-1));
    29     else printf("%d
    ",*upper_bound(A.begin(),A.end(),x));
    30     }
    31     return 0;
    32 }
    View Code

    (学习treap中,到时候再发)

    更新:

    液我A了!!!

    先上代码

      1 // It is made by XZZ
      2 #include<cstdio>
      3 using namespace std;
      4 #define rep(a,b,c) for(rg int a=b;a<=c;a++)
      5 #define drep(a,b,c) for(rg int a=b;a>=c;a--)
      6 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
      7 #define il inline
      8 #define rg register
      9 #define vd void
     10 #define Ls tree[now].ls
     11 #define Rs tree[now].rs
     12 typedef long long ll;
     13 il int gi(){
     14     rg int x=0,f=1;rg char ch=getchar();
     15     while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
     16     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
     17     return x*f;
     18 }
     19 struct node{
     20     int ls,rs,value,rand,sum,size;
     21     node(){ls=rs=value=rand=sum=size=0;}
     22 }tree[100001];
     23 int root=0,siz=0;
     24 ll seed=19260817;
     25 il int Rand(){return seed=seed*48271LL%2147483647;}
     26 il vd reset(int now){
     27     tree[now].size=tree[Ls].size+tree[Rs].size+tree[now].sum;
     28 }
     29 il vd lrot(int&now){
     30     int ls=tree[now].ls;
     31     tree[now].ls=tree[ls].rs,tree[ls].rs=now;
     32     tree[ls].size=tree[now].size;reset(now);now=ls;
     33 }
     34 il vd rrot(int&now){
     35     int rs=tree[now].rs;
     36     tree[now].rs=tree[rs].ls,tree[rs].ls=now;
     37     tree[rs].size=tree[now].size;reset(now);now=rs;
     38 }
     39 il vd ins(int&now,int num){
     40     if(now==0){
     41     ++siz,now=siz,tree[now].size=tree[now].sum=1,tree[now].value=num,tree[now].rand=Rand();
     42     return;
     43     }
     44     ++tree[now].size;
     45     if(tree[now].value==num)++tree[now].sum;
     46     else if(num<tree[now].value){
     47     ins(Ls,num);
     48     if(tree[Ls].rand<tree[now].rand)lrot(now);
     49     }else{
     50     ins(Rs,num);
     51     if(tree[Rs].rand<tree[now].rand)rrot(now);
     52     }
     53 }
     54 il vd del(int&now,int num){
     55     if(now==0)return;
     56     if(tree[now].value==num){
     57     if(tree[now].sum>1){--tree[now].sum,--tree[now].size;return;}
     58     if(!Ls||!Rs)now=Ls|Rs;
     59     else if(tree[Ls].rand<tree[Rs].rand)lrot(now),del(now,num);
     60     else rrot(now),del(now,num);
     61     return;
     62     }
     63     --tree[now].size;
     64     if(num<tree[now].value)del(Ls,num);
     65     else del(Rs,num);
     66 }
     67 il int getrank(int now,int num){
     68     if(now==0)return 0;
     69     if(tree[now].value==num)return tree[Ls].size+1;
     70     if(num>tree[now].value)return tree[Ls].size+tree[now].sum+getrank(Rs,num);
     71     else return getrank(Ls,num);
     72 }
     73 il int getnum(int now,int num){
     74     if(num<=tree[Ls].size)return getnum(Ls,num);
     75     else if(num>tree[Ls].size+tree[now].sum)return getnum(Rs,num-tree[Ls].size-tree[now].sum);
     76     else return tree[now].value;
     77 }
     78 int ans;
     79 il vd lower(int now,int num){
     80     if(now==0)return;
     81     if(tree[now].value<num)ans=now,lower(Rs,num);
     82     else lower(Ls,num);
     83 }
     84 il vd upper(int now,int num){
     85     if(now==0)return;
     86     if(tree[now].value>num)ans=now,upper(Ls,num);
     87     else upper(Rs,num);
     88 }
     89 int main(){
     90     int n=gi(),opt,x;
     91     while(n--){
     92     opt=gi(),x=gi();
     93     switch(opt){
     94         case 1:ins(root,x);break;
     95         case 2:del(root,x);break;
     96         case 3:printf("%d
    ",getrank(root,x));break;
     97         case 4:printf("%d
    ",getnum(root,x));break;
     98         case 5:ans=0,lower(root,x),printf("%d
    ",tree[ans].value);break;
     99         case 6:ans=0,upper(root,x),printf("%d
    ",tree[ans].value);break;
    100     }
    101     }
    102     return 0;
    103 }
    View Code
     因为太短了,写一点东西。。。
    treap==tree+heap
    因为二叉查找树很难平衡,所以加一个随机权值,当作一个堆维护
    所以treap既有tree性质又有heap性质
    当heap性质被破坏后用旋转来维护
    我们还可以把函数写成非递归的。。。
      1 // It is made by XZZ
      2 #include<cstdio>
      3 using namespace std;
      4 #define rep(a,b,c) for(rg int a=b;a<=c;a++)
      5 #define drep(a,b,c) for(rg int a=b;a>=c;a--)
      6 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
      7 #define il inline
      8 #define rg register
      9 #define vd void
     10 #define Ls tree[now].ls
     11 #define Rs tree[now].rs
     12 typedef long long ll;
     13 il int gi(){
     14     rg int x=0,f=1;rg char ch=getchar();
     15     while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
     16     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
     17     return x*f;
     18 }
     19 struct node{
     20     int ls,rs,value,rand,sum,size;
     21     node(){ls=rs=value=rand=sum=size=0;}
     22 }tree[100001];
     23 int root=0,siz=0;
     24 ll seed=19260817;
     25 il int Rand(){return seed=seed*48271LL%2147483647;}
     26 il vd reset(int now){
     27     tree[now].size=tree[Ls].size+tree[Rs].size+tree[now].sum;
     28 }
     29 il vd lrot(int&now){
     30     int ls=tree[now].ls;
     31     tree[now].ls=tree[ls].rs,tree[ls].rs=now;
     32     tree[ls].size=tree[now].size;reset(now);now=ls;
     33 }
     34 il vd rrot(int&now){
     35     int rs=tree[now].rs;
     36     tree[now].rs=tree[rs].ls,tree[rs].ls=now;
     37     tree[rs].size=tree[now].size;reset(now);now=rs;
     38 }
     39 il vd ins(int&now,int num){
     40     if(now==0){
     41     ++siz,now=siz,tree[now].size=tree[now].sum=1,tree[now].value=num,tree[now].rand=Rand();
     42     return;
     43     }
     44     ++tree[now].size;
     45     if(tree[now].value==num)++tree[now].sum;
     46     else if(num<tree[now].value){
     47     ins(Ls,num);
     48     if(tree[Ls].rand<tree[now].rand)lrot(now);
     49     }else{
     50     ins(Rs,num);
     51     if(tree[Rs].rand<tree[now].rand)rrot(now);
     52     }
     53 }
     54 il vd del(int&now,int num){
     55     if(now==0)return;
     56     if(tree[now].value==num){
     57     if(tree[now].sum>1){--tree[now].sum,--tree[now].size;return;}
     58     if(!Ls||!Rs)now=Ls|Rs;
     59     else if(tree[Ls].rand<tree[Rs].rand)lrot(now),del(now,num);
     60     else rrot(now),del(now,num);
     61     return;
     62     }
     63     --tree[now].size;
     64     if(num<tree[now].value)del(Ls,num);
     65     else del(Rs,num);
     66 }
     67 il int getrank(int now,int num){
     68     int Rank=0;
     69     while(now)if(tree[now].value==num)return tree[Ls].size+1+Rank;
     70         else if(num>tree[now].value)Rank+=tree[Ls].size+tree[now].sum,now=Rs;
     71     else now=Ls;
     72 }
     73 il int getnum(int now,int num){
     74     while(1)
     75         if(num<=tree[Ls].size)now=Ls;
     76         else if(num>tree[Ls].size+tree[now].sum)num-=tree[Ls].size+tree[now].sum,now=Rs;
     77         else return tree[now].value;
     78 }
     79 il int lower(int now,int num){
     80     int ret;
     81     while(now)if(tree[now].value<num)ret=tree[now].value,now=Rs;
     82         else now=Ls;
     83     return ret;
     84 }
     85 il int upper(int now,int num){
     86     int ret;
     87     while(now)if(tree[now].value>num)ret=tree[now].value,now=Ls;
     88         else now=Rs;
     89     return ret;
     90 }
     91 int main(){
     92     freopen("phs.in","r",stdin);
     93     freopen("phs.out","w",stdout);
     94     int n=gi(),opt,x;
     95     while(n--){
     96     opt=gi(),x=gi();
     97     switch(opt){
     98         case 1:ins(root,x);break;
     99         case 2:del(root,x);break;
    100             case 3:printf("%d
    ",getrank(root,x));break;
    101         case 4:printf("%d
    ",getnum(root,x));break;
    102         case 5:printf("%d
    ",lower(root,x));break;
    103         case 6:printf("%d
    ",upper(root,x));break;
    104     }
    105     }
    106     return 0;
    107 }
    View Code

    这样在cogs上可以从1.90s下降到1.70s

    在洛谷上可以从164ms上升到259ms(大雾)

    在bzoj上可以从300ms下降到296ms

    所以非递归到底有没有用???

  • 相关阅读:
    centos golang 环境配置
    运行安全审计 npm audit
    Oracle ——UTL_SMTP包发送Email
    UML学习入门就这一篇文章
    UML ——类图和对象图
    SQL SERVER 行列转换(转自别人)
    Oracle行列转换小结
    同步调用/异步调用(摘自百度)
    C#中Invoke的用法(Winform编程)
    udpclient之异步编程
  • 原文地址:https://www.cnblogs.com/xzz_233/p/7258931.html
Copyright © 2011-2022 走看看