[TYVJ1730]二逼平衡树

[TYVJ1730]二逼平衡树

题目

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
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

OUTPUT

2
4
3
4
9

解题报告

线段树套平衡树裸题,瞎XX打,轻松1A

别问我为啥BZOJ上RE了一次,srand有毒

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<cstdio>
  5 #include<ctime>
  6 using namespace std;
  7 inline int read(){
  8     int sum(0),f(1);
  9     char ch(getchar());
 10     for(;ch<'0'||ch>'9';ch=getchar())
 11         if(ch=='-')
 12             f=-1;
 13     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
 14     return sum*f;
 15 }
 16 #define get_size(x) (x?x->size:0)
 17 struct node{
 18     node *lch,*rch;
 19     int size,key,fix;
 20     node(int x=0):lch(NULL),rch(NULL),size(1),key(x),fix(rand()){}
 21     inline void pushup(){
 22         this->size=get_size(this->lch)+get_size(this->rch)+1;
 23     }
 24 }*tr[200005];
 25 inline void left_rotate(node *&x){
 26     node *tmp(x->rch);
 27     x->rch=tmp->lch;
 28     tmp->lch=x;
 29     x->pushup();
 30     tmp->pushup();
 31     x=tmp;
 32 }
 33 inline void right_rotate(node *&x){
 34     node *tmp(x->lch);
 35     x->lch=tmp->rch;
 36     tmp->rch=x;
 37     x->pushup();
 38     tmp->pushup();
 39     x=tmp;
 40 }
 41 inline void insert(node *&x,int v){
 42     if(!x){
 43         x=new node(v);
 44         return;
 45     }
 46     if(v<=x->key){
 47         insert(x->lch,v);
 48         x->pushup();
 49         if(x->lch->fix<x->fix)
 50             right_rotate(x);
 51     }
 52     else{
 53         insert(x->rch,v);
 54         x->pushup();
 55         if(x->rch->fix<x->fix)
 56             left_rotate(x);
 57     }
 58 }
 59 inline void del(node *&x,int v){
 60     if(x->key==v){
 61         if(x->lch&&x->rch){
 62             if(x->lch->fix<x->rch->fix){
 63                 right_rotate(x);
 64                 del(x->rch,v);
 65             }
 66             else{
 67                 left_rotate(x);
 68                 del(x->lch,v);
 69             }
 70         }
 71         else{
 72             node *tmp(NULL);
 73             if(x->lch)
 74                 tmp=x->lch;
 75             else
 76                 tmp=x->rch;
 77             delete x;
 78             x=tmp;
 79         }
 80     }
 81     else{
 82         if(v<=x->key)
 83             del(x->lch,v);
 84         else
 85             del(x->rch,v);
 86     }
 87     if(x)
 88         x->pushup();
 89 }
 90 inline int Rank(node *now,int x){
 91     int ret(0);
 92     while(now){
 93         if(x<=now->key)
 94             now=now->lch;
 95         else
 96             ret+=get_size(now->lch)+1,now=now->rch;
 97     }
 98     return ret;
 99 }
100 inline int kth(node *now,int k){
101     while(now){
102         if(get_size(now->lch)+1==k)
103             return now->key;
104         if(get_size(now->lch)+1>=k)
105             now=now->lch;
106         else
107             k-=get_size(now->lch)+1,now=now->rch;
108     }
109 }
110 int n,m;
111 int a[50005];
112 inline void build(int l,int r,int rt){
113     for(int i=l;i<=r;++i)
114         insert(tr[rt],a[i]);
115     if(l==r)return;
116     int mid((l+r)>>1);
117     build(l,mid,rt<<1);
118     build(mid+1,r,rt<<1|1);
119 }
120 inline int Rank(int ll,int rr,int k,int l,int r,int i){
121     if(ll<=l&&r<=rr)
122         return Rank(tr[i],k);
123     int mid((l+r)>>1),ret(0);
124     if(ll<=mid)
125         ret+=Rank(ll,rr,k,l,mid,i<<1);
126     if(mid<rr)
127         ret+=Rank(ll,rr,k,mid+1,r,i<<1|1);
128     return ret;
129 }
130 inline int kth(int l,int r,int k){
131     int ll(1),rr(1e8);
132     while(ll<=rr){
133         int mid((ll+rr)>>1);
134         int jud(Rank(l,r,mid,1,n,1)+1);
135         if(jud<=k)
136             ll=mid+1;
137         else
138             rr=mid-1;
139     }
140     return rr;
141 }
142 inline void update(int pos,int w,int l,int r,int i){
143     del(tr[i],a[pos]);
144     insert(tr[i],w);
145     if(l==r)return;
146     int mid((l+r)>>1);
147     if(pos<=mid)
148         update(pos,w,l,mid,i<<1);
149     else
150         update(pos,w,mid+1,r,i<<1|1);
151 }
152 inline int gg(){
153 //    freopen("psh.in","r",stdin);
154 //    freopen("psh.out","w",stdout);
155 //    srand(time(NULL));
156     n=read(),m=read();
157     for(int i=1;i<=n;++i)
158         a[i]=read();
159     build(1,n,1);
160     while(m--){
161         int op(read());
162         if(op==1){
163             int x(read()),y(read()),z(read());
164             printf("%d\n",Rank(x,y,z,1,n,1)+1);
165         }
166         if(op==2){
167             int x(read()),y(read()),z(read());
168             printf("%d\n",kth(x,y,z));
169         }
170         if(op==3){
171             int x(read()),y(read());
172             update(x,y,1,n,1);
173             a[x]=y;
174         }
175         if(op==4){
176             int x(read()),y(read()),z(read());
177             printf("%d\n",kth(x,y,Rank(x,y,z,1,n,1)));
178         }
179         if(op==5){
180             int x(read()),y(read()),z(read());
181             printf("%d\n",kth(x,y,Rank(x,y,z+1,1,n,1)+1));
182         }
183     }
184     return 0;
185 }
186 int K(gg());
187 int main(){;}
View Code

 

转载于:https://www.cnblogs.com/hzoi-mafia/p/7635418.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值