• BZOJ 3224: Tyvj 1728 普通平衡树


    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 9286  Solved: 3935
    [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.每个数的数据范围:[-1e7,1e7]

    数据如下http://pan.baidu.com/s/1jHMJwO2

    Source

    分析:

    还是模板题...讲道理这道题我写了3遍才AC...QAQ...

    代码:

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 //by NeighThorn
      6 #define inf 1e7+7
      7 using namespace std;
      8 
      9 const int maxn=100000+5;
     10 
     11 int n,opt;
     12 int root,tot,w[maxn],ls[maxn],rs[maxn],fa[maxn],cnt[maxn],siz[maxn];
     13 
     14 inline void zig(int x){
     15     int y=fa[x],tmp=siz[y];
     16     if(rs[x])
     17         ls[y]=rs[x],fa[rs[x]]=y,siz[y]=siz[y]-siz[x]+siz[rs[x]],siz[x]=tmp;
     18     else
     19         ls[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
     20     fa[x]=fa[y];
     21     if(fa[x]){
     22         if(ls[fa[x]]==y)
     23             ls[fa[x]]=x;
     24         else
     25             rs[fa[x]]=x;
     26     }
     27     fa[y]=x,rs[x]=y;
     28 }
     29 
     30 inline void zag(int x){
     31     int y=fa[x],tmp=siz[y];
     32     if(ls[x])
     33         rs[y]=ls[x],fa[ls[x]]=y,siz[y]=siz[y]-siz[x]+siz[ls[x]],siz[x]=tmp;
     34     else
     35         rs[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
     36     fa[x]=fa[y];
     37     if(fa[x]){
     38         if(ls[fa[x]]==y)
     39             ls[fa[x]]=x;
     40         else
     41             rs[fa[x]]=x;
     42     }
     43     fa[y]=x,ls[x]=y;
     44 }
     45 
     46 inline void splay(int x,int z){
     47     while(fa[x]!=z){
     48         int y=fa[x];
     49         if(fa[y]==z){
     50             if(ls[y]==x)
     51                 zig(x);
     52             else
     53                 zag(x);
     54         }
     55         else{
     56             if(ls[fa[y]]==y){
     57                 if(ls[y]==x)
     58                     zig(y),zig(x);
     59                 else
     60                     zag(x),zig(x);
     61             }
     62             else{
     63                 if(rs[y]==x)
     64                     zag(y),zag(x);
     65                 else
     66                     zig(x),zag(x);
     67             }
     68         }
     69     }
     70     if(!z)
     71         root=x;
     72 }
     73 
     74 inline void ins(int rt,int x){
     75     if(!rt)
     76         w[++tot]=x,siz[tot]=1,cnt[tot]=1,root=tot;
     77     else if(w[rt]==x)
     78         cnt[rt]++,siz[rt]++,splay(rt,0);
     79     else if(x<w[rt]){
     80         if(!ls[rt])
     81             w[++tot]=x,cnt[tot]=siz[tot]=1,siz[rt]++,fa[tot]=rt,ls[rt]=tot,splay(tot,0);
     82         else
     83             siz[rt]++,ins(ls[rt],x);
     84     }
     85     else{
     86         if(!rs[rt])
     87             w[++tot]=x,cnt[tot]=siz[tot]=1,siz[rt]++,fa[tot]=rt,rs[rt]=tot,splay(tot,0);
     88         else
     89             siz[rt]++,ins(rs[rt],x);
     90     }
     91 }
     92 
     93 inline void del(int rt,int x){
     94     if(w[rt]==x){
     95         splay(rt,0);
     96         if(cnt[rt]>1)
     97             cnt[rt]--,siz[rt]--;
     98         else{
     99             int l=ls[rt],r=rs[rt];
    100             if(!l)
    101                 ls[rt]=rs[rt]=fa[rt]=siz[rt]=cnt[rt]=0,fa[r]=0,root=r;
    102             else{
    103                 while(rs[l])
    104                     l=rs[l];
    105                 splay(l,rt);ls[rt]=rs[rt]=fa[rt]=siz[rt]=cnt[rt]=0;fa[r]=l,rs[l]=r,siz[l]+=siz[r];root=l,fa[l]=0;
    106             }
    107         }
    108     }
    109     else if(x<w[rt])
    110         del(ls[rt],x);
    111     else
    112         del(rs[rt],x);
    113 }
    114 
    115 inline int pre(int rt,int x){
    116     int res=-inf;
    117     while(rt){
    118         if(w[rt]<x)
    119             res=max(res,w[rt]),rt=rs[rt];
    120         else
    121             rt=ls[rt];
    122     }
    123     return res;
    124 }
    125 
    126 inline int suf(int rt,int x){
    127     int res=inf;
    128     while(rt){
    129         if(w[rt]>x)
    130             res=min(res,w[rt]),rt=ls[rt];
    131         else
    132             rt=rs[rt];
    133     }
    134     return res;
    135 }
    136 
    137 inline int rank(int rt,int x){
    138     if(w[rt]==x){
    139         splay(rt,0);
    140         if(!ls[rt])
    141             return 1;
    142         else
    143             return siz[ls[rt]]+1;
    144     }
    145     else if(x<w[rt])
    146         return rank(ls[rt],x);
    147     else
    148         return rank(rs[rt],x);
    149 }
    150 
    151 inline int query(int rt,int x){
    152     if(!ls[rt]){
    153         if(cnt[rt]>=x){
    154             splay(rt,0);
    155             return w[rt];
    156         }
    157         else
    158             return query(rs[rt],x-cnt[rt]);
    159     }
    160     else{
    161         if(siz[ls[rt]]>=x)
    162             return query(ls[rt],x);
    163         else if(siz[ls[rt]]+cnt[rt]>=x){
    164             splay(rt,0);
    165             return w[rt];
    166         }
    167         else
    168             return query(rs[rt],x-siz[ls[rt]]-cnt[rt]);
    169     }
    170 }
    171 
    172 signed main(void){
    173     memset(ls,0,sizeof(ls));
    174     memset(rs,0,sizeof(rs));
    175     memset(fa,0,sizeof(fa));
    176     memset(cnt,0,sizeof(cnt));
    177     memset(siz,0,sizeof(siz));
    178     scanf("%d",&n);root=tot=0;
    179     for(int i=1,x;i<=n;i++){
    180         scanf("%d%d",&opt,&x);
    181         if(opt==1)
    182             ins(root,x);
    183         else if(opt==2)
    184             del(root,x);
    185         else if(opt==3)
    186             printf("%d
    ",rank(root,x));
    187         else if(opt==4)
    188             printf("%d
    ",query(root,x));
    189         else if(opt==5)
    190             printf("%d
    ",pre(root,x));
    191         else
    192             printf("%d
    ",suf(root,x));
    193     }    
    194     return 0;
    195 }
    View Code

    by NeighThorn

  • 相关阅读:
    php 将网页执行的输出写入到本地文件中
    网络爬虫技术
    解决:解压zip文件却变成cpgz文件
    SHA1算法实现及详解
    Mac配置PHP开发环境
    项目管理
    Oracle Primavera P6 R84单机版安装教程
    工时
    项目管理软件伙伴https://www.huobanyun.cn/
    Primavera 6.0
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6155065.html
Copyright © 2020-2023  润新知