zoukankan      html  css  js  c++  java
  • BZOJ 3196 二逼平衡树

    题面:

    3196: Tyvj 1730 二逼平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 4026  Solved: 1551
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
    1.查询k在区间内的排名
    2.查询区间内排名为k的值
    3.修改某一位值上的数值
    4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
    5.查询k在区间内的后继(后继定义为大于x,且最小的数)

    Input

    第一行两个数 n,m 表示长度为n的有序序列和m个操作
    第二行有n个数,表示有序序列
    下面有m行,opt表示操作标号
    若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
    若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
    若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
    若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
    若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

    Output

    对于操作1,2,4,5各输出一行,表示查询结果

    Sample Input

    9 6
    4 2 2 1 9 4 0 1 1
    2 1 4 3
    3 4 10
    2 1 4 3
    1 2 5 9
    4 3 9 5
    5 2 8 5

    Sample Output

    2
    4
    3
    4
    9

    HINT

    1.n和m的数据范围:n,m<=50000

    2.序列中每个数的数据范围:[0,1e8]

    3.虽然原题没有,但事实上5操作的k可能为负数
     
    线段树+splay(SBT死活调不过,还是splay大法吼!)
      1 #include<stdio.h>
      2 using namespace std;
      3 #define maxn 60001
      4 #define INF 1<<30
      5 #define max(a,b) a>b?a:b
      6 #define min(a,b) a<b?a:b
      7 struct node
      8 {
      9     int w,size,count;
     10     node *fa,*son[2];
     11 }tree[maxn<<4],*stk[maxn<<4];
     12 int top,indx;
     13 int s[maxn],n,m;
     14 class Splay
     15 {
     16     private:
     17         node *newnode(int w,node *f)
     18         {
     19             node *t;
     20             if(top)t=stk[--top];
     21             else t=&tree[indx++];
     22             t->w=w;t->size=t->count=1;
     23             t->fa=f;t->son[0]=t->son[1]=NULL;
     24             return t;
     25         }
     26         inline void update(node *t)
     27         {
     28             if(t==NULL)
     29                 return ;
     30             t->size=t->count+size(t->son[0])+size(t->son[1]);
     31         }
     32         inline void freenode(node *t)
     33         {
     34             stk[top++]=t;
     35         }
     36         inline bool Son(node *f,node *t)
     37         {
     38             return f==NULL?0:f->son[1]==t;
     39         }
     40         inline int size(node *t)
     41         {
     42             return t==NULL?0:t->size;
     43         }
     44         inline void connect(node *f,node *t,bool flag)
     45         {
     46             if(f==NULL) root=t;
     47             else f->son[flag]=t;
     48             if(t!=NULL)t->fa=f;
     49         }
     50         void rotate(node *t)
     51         {
     52             node *f=t->fa;node *g=f->fa;
     53             bool a=Son(f,t),b=!a;
     54             connect(f,t->son[b],a);
     55             connect(g,t,Son(g,f));
     56             connect(t,f,b);
     57             update(f);update(t);
     58         }
     59         void splay(node *t,node *p)
     60         {
     61             if(t==NULL)return ;
     62             node *f,*g;
     63             while(t->fa!=p)
     64             {
     65                 f=t->fa;g=f->fa;
     66                 if(g==p)rotate(t);
     67                 else
     68                     if(Son(f,t)^Son(g,f))rotate(t),rotate(t);
     69                     else rotate(f),rotate(t);
     70             }
     71         }
     72         node *find(int w)
     73         {
     74             node *t=root;
     75             while(t!=NULL&&t->w!=w)t=t->son[w>=t->w];
     76             return splay(t,NULL),t;
     77         }
     78         node *insert(node *t,int w)
     79         {
     80             node *p=t->son[w>=t->w];
     81             if(p==NULL)p=t->son[w>=t->w]=newnode(w,t);
     82             else p=insert(p,w);
     83             return update(t),p;
     84         }
     85         void erase(node *t)
     86         {
     87             if(t->son[0]==NULL)
     88             {
     89                 connect(NULL,t->son[1],0);update(root);
     90             }
     91             else
     92                 if(t->son[1]==NULL)
     93                 {
     94                     connect(NULL,t->son[0],0);update(root);
     95                 }
     96                 else
     97                 {
     98                     node *p=t->son[0];
     99                     while(p->son[1]!=NULL)p=p->son[1];
    100                     splay(p,t);connect(NULL,p,0);
    101                     connect(p,t->son[1],1);update(root);
    102                 }
    103             freenode(t);
    104         }
    105         void erase(node *t,int k)
    106         {
    107             t->count-=k;
    108             if(t->count<=0)erase(t);
    109             else update(t);
    110         }
    111         public:
    112             int l,r;node *root;
    113             Splay(){}
    114             void insert(int w)
    115             {
    116                 if(find(w)!=NULL)++root->count,update(root);
    117                 else
    118                     if(root==NULL)  root=newnode(w,NULL);
    119                     else splay(insert(root,w),NULL);
    120             }
    121             void erase(int w)
    122             {
    123                 if(find(w)!=NULL)erase(root,1);
    124             }
    125             int pre(int w)
    126             {
    127                 int ans=-INF;
    128                 for(node *t=root;t!=NULL;)
    129                 {
    130                     if(w>t->w)ans=max(ans,t->w);
    131                     t=t->son[w>t->w];
    132                 }
    133                 return ans;
    134             }
    135             int suc(int w)
    136             {
    137                 int ans=INF;
    138                 for(node *t=root;t!=NULL;)
    139                 {
    140                     if(w<t->w)ans=min(ans,t->w);
    141                     t=t->son[w>=t->w];
    142                 }
    143                 return ans;
    144             }
    145             int RANK(node *t,int w)
    146             {
    147                 if(!t)return 0;
    148                 if(t->w==w)return size(t->son[0]);
    149                 if(t->w>w)return RANK(t->son[0],w);
    150                 return size(t->son[0])+t->count+RANK(t->son[1],w);
    151             }
    152 }a[maxn<<2];
    153 int ret;
    154 void build(int id,int l,int r)
    155 {
    156      
    157     a[id].l=l,a[id].r=r;
    158     for(int i=l;i<=r;i++)
    159         a[id].insert(s[i]);
    160     if(l==r)
    161         return ;
    162     int mid=(l+r)>>1;
    163     build(id<<1,l,mid);
    164     build(id<<1|1,mid+1,r);
    165 }
    166 void change(int id,int p,int w)
    167 {
    168     a[id].erase(s[p]);a[id].insert(w);
    169     if(a[id].l==a[id].r)return ;
    170     int mid=(a[id].l+a[id].r)>>1;
    171     if(p<=mid)change(id<<1,p,w);
    172     else change(id<<1|1,p,w);
    173 }
    174 int query_pre(int id,int l,int r,int w)
    175 {
    176     if(l<=a[id].l&&a[id].r<=r)
    177         return a[id].pre(w);
    178     int mid=(a[id].l+a[id].r)>>1;
    179     if(r<=mid)
    180         return query_pre(id<<1,l,r,w);
    181     else
    182         if(l>mid)
    183             return query_pre(id<<1|1,l,r,w);
    184         else   
    185             return max(query_pre(id<<1,l,mid,w),query_pre(id<<1|1,mid+1,r,w));
    186 }
    187 int query_suc(int id,int l,int r,int w)
    188 {
    189     if(l<=a[id].l&&a[id].r<=r)
    190         return a[id].suc(w);
    191     int mid=(a[id].l+a[id].r)>>1;
    192     if(r<=mid)
    193         return query_suc(id<<1,l,r,w);
    194     else
    195         if(l>mid)
    196             return query_suc(id<<1|1,l,r,w);
    197         else   
    198             return min(query_suc(id<<1,l,mid,w),query_suc(id<<1|1,mid+1,r,w));
    199 }
    200 void query_rank(int id,int l,int r,int w)
    201 {
    202     if(l<=a[id].l&&a[id].r<=r)
    203     {
    204         ret+=a[id].RANK(a[id].root,w);
    205         return ;
    206     }
    207     int mid=(a[id].l+a[id].r)>>1;
    208     if(r<=mid)
    209         query_rank(id<<1,l,r,w);
    210     else
    211         if(l>mid)
    212             query_rank(id<<1|1,l,r,w);
    213         else
    214             query_rank(id<<1,l,mid,w),query_rank(id<<1|1,mid+1,r,w);
    215 }
    216 int query_kth(int l,int r,int k)
    217 {
    218     int L=0,R=1e9,mid,ans;
    219     while(L!=R)
    220     {
    221         mid=(L+R)>>1;
    222         ret=0;
    223         query_rank(1,l,r,mid);
    224         if(ret<k)
    225             L=mid+1;
    226         else
    227             R=mid;
    228     }
    229     return L-1;
    230 }
    231 int main()
    232 {
    233     int op,l,r,k;
    234     int x,y;
    235     scanf("%d%d",&n,&m);
    236     for(int i=1;i<=n;i++)
    237         scanf("%d",&s[i]);
    238     build(1,1,n);
    239     for(int i=1;i<=m;i++)
    240     {
    241         scanf("%d",&op);
    242         switch(op)
    243         {
    244             case 1:
    245                 scanf("%d%d%d",&l,&r,&k);
    246                 ret=0;
    247                 query_rank(1,l,r,k);
    248                 printf("%d
    ",ret+1);
    249                 break;
    250             case 2:
    251                 scanf("%d%d%d",&l,&r,&k);
    252                 printf("%d
    ",query_kth(l,r,k));
    253                 break;
    254             case 3:
    255                 scanf("%d%d",&x,&y);
    256                 change(1,x,y);
    257                 s[x]=y;
    258                 break;
    259             case 4:
    260                 scanf("%d%d%d",&l,&r,&k);
    261                 printf("%d
    ",query_pre(1,l,r,k));
    262                 break;
    263             case 5:
    264                 scanf("%d%d%d",&l,&r,&k);
    265                 printf("%d
    ",query_suc(1,l,r,k));
    266                 break;
    267         }
    268     }
    269 }
    BZOJ 3196
  • 相关阅读:
    记-码农的“启蒙”之《程序设计语言-实践之路》和《面向对象分析和设计》两书
    记-阅读以及书籍推荐(2014年9月7日更新)
    初探领域驱动设计(1)为复杂业务而生
    异步编程 In .NET
    Windows平台分布式架构实践
    Windows平台分布式架构实践
    一不小心写了个WEB服务器
    MVC5
    从Membership 到 .NET4.5 之 ASP.NET Identity
    bootstrap + requireJS+ director+ knockout + web API = 一个时髦的单页程序
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7275937.html
Copyright © 2011-2022 走看看