• Bzoj3224 / Tyvj 1728 普通替罪羊树


    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 12015  Solved: 5136

    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

    替罪羊树

    曾经我一直以为替罪羊树就是不平衡的时候拍扁了重建……

    真是拿衣服

    从yhx那里get了神奇的删点方法:找到它的前驱pre,用pre代替它←虽然只有一句话,但这是整道题最麻烦的地方

    http://blog.csdn.net/sdfzyhx/article/details/70212142

    代码里同时用到了st,top,st2,top2两组变量,写的时候我还在想这样会不会写混,事实证明果然写混调了半天…… 

      1 /*by SilverN*/
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 using namespace std;
      9 const int mxn=120010;
     10 int read(){
     11     int x=0,f=1;char ch=getchar();
     12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     14     return x*f;
     15 }
     16 struct node{
     17     int l,r;
     18     int val,sz;
     19     int cnt;
     20     bool operator < (const node b)const{
     21         return val<b.val;
     22     }
     23 }t[mxn],vt[mxn];
     24 int rot=0;
     25 int sz=0,cnt=0;
     26 int st[mxn],top=0;
     27 int flag=0,faf;
     28 int newnode(){
     29     int res=0;
     30     if(top)res=st[top--];
     31     else res=++cnt;
     32     t[res].sz=t[res].l=t[res].r=t[res].cnt=0;
     33     return res;
     34 }
     35 void pushup(int x){
     36     t[x].sz=t[t[x].l].sz+t[t[x].r].sz+t[x].cnt;return;
     37 }
     38 void Build(int l,int r,int &rt){
     39     if(l>r){rt=0;return;}
     40     int mid=(l+r)>>1;
     41     rt=newnode();
     42     t[rt].val=vt[mid].val;
     43     t[rt].cnt=vt[mid].cnt;
     44     t[rt].sz=t[rt].cnt;
     45     Build(l,mid-1,t[rt].l);
     46     Build(mid+1,r,t[rt].r);
     47     pushup(rt);
     48     return;
     49 }
     50 void insert(int &rt,int x){
     51     if(!rt){
     52         rt=newnode();
     53         t[rt].val=x;
     54         t[rt].cnt=t[rt].sz=1;
     55         return;
     56     }
     57     t[rt].sz++;
     58     if(t[rt].val==x){
     59         t[rt].cnt++;
     60         return;
     61     }
     62     if(x<t[rt].val)insert(t[rt].l,x);
     63     else insert(t[rt].r,x);
     64     if(t[t[rt].l].sz/(double)t[rt].sz>0.666)flag=rt;
     65     if(flag==t[rt].l || flag==t[rt].r)faf=rt;
     66     pushup(rt);
     67     return;
     68 }
     69 void del(int rt){
     70     if(!rt)return;
     71     vt[++sz]=t[rt];
     72     st[++top]=rt;
     73     del(t[rt].l);
     74     del(t[rt].r);
     75     return;
     76 }
     77 int pre(int rt,int x){
     78     int res=-2e9-1,pos=0;
     79     while(rt){
     80         if(t[rt].val>=x){
     81             rt=t[rt].l;
     82         }
     83         else{
     84             if(t[rt].val>res){res=t[rt].val;pos=rt;}
     85             rt=t[rt].r;
     86         }
     87     }
     88     return pos;
     89 }
     90 int sub(int rt,int x){
     91     int res=2e9+1,pos=0;
     92     while(rt){
     93         if(t[rt].val<=x){
     94             rt=t[rt].r;
     95         }
     96         else{
     97             if(t[rt].val<res){res=t[rt].val;pos=rt;}
     98             rt=t[rt].l;
     99         }
    100     }
    101     return pos;
    102 }
    103 int st2[mxn],top2=0,fafa;
    104 void Q_erase(int &rt,int x){
    105 //    if(!rt && x==299181)while(1);
    106     if(t[rt].val==x){
    107         t[rt].cnt--;
    108         t[rt].sz--;
    109         if(!t[rt].cnt){
    110             if(t[rt].l*t[rt].r==0){rt=t[rt].l+t[rt].r;return;}
    111             int p=t[rt].l;
    112             while(t[p].r){st2[++top2]=p;p=t[p].r;}
    113             if(top2){
    114                 t[st2[top2]].r=t[p].l;
    115                 pushup(st2[top2]);
    116                 t[p].l=t[rt].l;
    117                 t[p].r=t[rt].r;
    118                 while(top2)pushup(st2[top2--]);
    119             }
    120             else t[p].r=t[rt].r;
    121             if(fafa){
    122                 if(t[fafa].l==rt) t[fafa].l=p;
    123                 else t[fafa].r=p;
    124             }
    125             pushup(p);
    126             pushup(t[rt].l);
    127             rt=p;
    128         }
    129         pushup(fafa);
    130         return;
    131     }
    132     fafa=rt;
    133     if(x<t[rt].val)Q_erase(t[rt].l,x);
    134     else Q_erase(t[rt].r,x);
    135     pushup(rt);
    136     return;
    137 }
    138 int Q_rank(int rt,int x){
    139     int res=0;
    140     while(rt){
    141         if(t[rt].val<x){
    142             res+=t[t[rt].l].sz+t[rt].cnt;
    143             rt=t[rt].r;
    144         }
    145         else rt=t[rt].l;
    146     }
    147     return res+1;
    148 }
    149 int Q_num(int rt,int k){
    150     int res=0;
    151     while(rt){
    152         if(t[t[rt].l].sz>=k){
    153             res=t[rt].val;
    154             rt=t[rt].l;
    155         }
    156         else if(t[t[rt].l].sz+t[rt].cnt>=k)return t[rt].val;
    157             else k-=t[t[rt].l].sz+t[rt].cnt,rt=t[rt].r;
    158     }
    159     return res;
    160 }
    161 void Debug(int x){
    162     if(!x)return;
    163     printf("#%d: v:%d l:%d r:%d sz:%d cnt:%d
    ",
    164         x,t[x].val,t[x].l,t[x].r,t[x].sz,t[x].cnt);
    165     Debug(t[x].l);Debug(t[x].r);
    166 }
    167 int n;
    168 int main(){
    169 //    freopen("in.txt","r",stdin);
    170 //    freopen("out.out","w",stdout);
    171     int i,j;
    172     n=read();
    173     int op,x;
    174     int tct=0;
    175     while(n--){
    176         op=read();x=read();
    177         if(op!=1)tct++;
    178         switch(op){
    179             case 1:{
    180                 flag=faf=0;sz=0;
    181                 insert(rot,x);
    182                 if(flag){
    183                     del(flag);
    184                     sort(vt+1,vt+sz+1);
    185                     if(flag==rot)Build(1,sz,rot);
    186                     else Build(1,sz,(t[faf].l==flag)?t[faf].l:t[faf].r);
    187                 }
    188                 break;
    189             }
    190             case 2:{fafa=0;Q_erase(rot,x);break;}
    191             case 3:{
    192                 int ans=Q_rank(rot,x);
    193                 printf("%d
    ",ans);
    194                 break;
    195             }
    196             case 4:{
    197                 int ans=Q_num(rot,x);
    198                 printf("%d
    ",ans);
    199                 break;
    200             }
    201             case 5:{
    202                 int res=pre(rot,x);
    203                 printf("%d
    ",t[res].val);
    204                 break;
    205             }
    206             case 6:{
    207                 int res=sub(rot,x);
    208                 printf("%d
    ",t[res].val);
    209                 break;
    210             }
    211             case 7:{
    212                 Debug(rot);
    213                 break;
    214             }
    215         }
    216     }
    217     return 0;
    218 }
  • 相关阅读:
    C# WinForm 创建XML文件方法总结
    VB中的ADO数据对象编程详解[转载]
    01.15 10日沙盘Top20分析
    IPad上做开发——在线B/S开发表单
    沙盘选股失败:延迟性与随机性
    IPad上做开发——在线B/S用户定制型通用列表
    IL动态调试.NET 程序(without pdb files)
    IPad上做开发——在线B/S开发主从表
    01.17 10日沙盘Top20分析
    IIS7下配置WCF的netTcpBinding
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6728686.html
Copyright © 2020-2023  润新知