1. 程式人生 > >[TYVJ1730]二逼平衡樹

[TYVJ1730]二逼平衡樹

isp 有序 spa blog 一個 rand left cti 數列

[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

[TYVJ1730]二逼平衡樹