[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 5OUTPUT
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(){;}