1 #include<cstdio> 2 #include<ctime> 3 #include<cstdlib> 4 #include<iostream> 5 #define M 3000009 6 using namespace std; 7 struct shu 8 { 9 int l,r,sum1,zhi,dui,sum2; 10 }a[M]; 11 int n,root[M],size,ans,b[M],m; 12 void you(int &a1) 13 { 14 int t=a[a1].l; 15 a[a1].l=a[t].r; 16 a[t].r=a1; 17 a[t].sum1=a[a1].sum1; 18 a[a1].sum1=a[a[a1].l].sum1+a[a[a1].r].sum1+a[a1].sum2; 19 a1=t; 20 return; 21 } 22 void zuo(int &a1) 23 { 24 int t=a[a1].r; 25 a[a1].r=a[t].l; 26 a[t].l=a1; 27 a[t].sum1=a[a1].sum1; 28 a[a1].sum1=a[a[a1].l].sum1+a[a[a1].r].sum1+a[a1].sum2; 29 a1=t; 30 return; 31 } 32 void cha(int &a1,int a2) 33 { 34 if(!a1) 35 { 36 size++; 37 a1=size; 38 a[a1].sum1=1; 39 a[a1].sum2=1; 40 a[a1].zhi=a2; 41 a[a1].dui=rand(); 42 return; 43 } 44 a[a1].sum1++; 45 if(a[a1].zhi==a2) 46 { 47 a[a1].sum2++; 48 return; 49 } 50 if(a2<a[a1].zhi) 51 { 52 cha(a[a1].l,a2); 53 if(a[a[a1].l].dui<a[a1].dui) 54 you(a1); 55 } 56 else 57 { 58 cha(a[a1].r,a2); 59 if(a[a[a1].r].dui<a[a1].dui) 60 zuo(a1); 61 } 62 } 63 void shan(int &a1,int a2) 64 { 65 if(a1==0) 66 return; 67 if(a[a1].zhi==a2) 68 { 69 if(a[a1].sum2>1) 70 { 71 a[a1].sum2--; 72 a[a1].sum1--; 73 } 74 else if(a[a1].l*a[a1].r==0) 75 a1=a[a1].l+a[a1].r; 76 else if(a[a[a1].l].dui<a[a[a1].r].dui) 77 { 78 you(a1); 79 shan(a1,a2); 80 } 81 else 82 { 83 zuo(a1); 84 shan(a1,a2); 85 } 86 return; 87 } 88 a[a1].sum1--; 89 if(a[a1].zhi<a2) 90 shan(a[a1].r,a2); 91 else 92 shan(a[a1].l,a2); 93 return; 94 } 95 int cha1(int a1,int a2) 96 { 97 if(!a1) 98 return 0; 99 if(a[a1].zhi==a2) 100 return a[a[a1].l].sum1; 101 if(a[a1].zhi>a2) 102 return cha1(a[a1].l,a2); 103 return a[a[a1].l].sum1+a[a1].sum2+cha1(a[a1].r,a2); 104 } 105 void qian(int a1,int a2) 106 { 107 if(!a1) 108 return; 109 if(a[a1].zhi<a2) 110 { 111 ans=max(a[a1].zhi,ans); 112 qian(a[a1].r,a2); 113 } 114 else 115 qian(a[a1].l,a2); 116 return; 117 } 118 void hou(int a1,int a2) 119 { 120 if(!a1) 121 return; 122 if(a[a1].zhi>a2) 123 { 124 ans=min(a[a1].zhi,ans); 125 hou(a[a1].l,a2); 126 } 127 else 128 hou(a[a1].r,a2); 129 return; 130 } 131 void build(int a1,int l,int r,int x,int v) 132 { 133 cha(root[a1],v); 134 if(l==r) 135 return; 136 int mid=(l+r)>>1; 137 if(x<=mid) 138 build(a1*2,l,mid,x,v); 139 else 140 build(a1*2+1,mid+1,r,x,v); 141 return; 142 } 143 void xicha1(int a1,int l,int r,int l1,int r1,int x) 144 { 145 if(l1<=l&&r1>=r) 146 { 147 ans+=cha1(root[a1],x); 148 return; 149 } 150 int mid=(l+r)>>1; 151 if(l1<=mid) 152 xicha1(a1*2,l,mid,l1,r1,x); 153 if(r1>mid) 154 xicha1(a1*2+1,mid+1,r,l1,r1,x); 155 return; 156 } 157 void xicha2(int l1,int r1,int x) 158 { 159 int l2=0,r2=100000000,q=0; 160 for(;l2<=r2;) 161 { 162 int mid=(l2+r2)>>1; 163 ans=1; 164 xicha1(1,1,n,l1,r1,mid); 165 if(ans<=x) 166 { 167 q=mid; 168 l2=mid+1; 169 } 170 else 171 r2=mid-1; 172 } 173 printf("%d ",q); 174 } 175 void change(int a1,int l,int r,int l1,int x,int y) 176 { 177 shan(root[a1],y); 178 cha(root[a1],x); 179 if(l==r) 180 return; 181 int mid=(l+r)>>1; 182 if(l1<=mid) 183 change(a1*2,l,mid,l1,x,y); 184 else 185 change(a1*2+1,mid+1,r,l1,x,y); 186 return; 187 } 188 void xiqian(int a1,int l,int r,int l1,int r1,int x) 189 { 190 if(l1<=l&&r1>=r) 191 { 192 qian(root[a1],x); 193 return; 194 } 195 int mid=(l+r)>>1; 196 if(l1<=mid) 197 xiqian(a1*2,l,mid,l1,r1,x); 198 if(r1>mid) 199 xiqian(a1*2+1,mid+1,r,l1,r1,x); 200 return; 201 } 202 void xihou(int a1,int l,int r,int l1,int r1,int x) 203 { 204 if(l1<=l&&r1>=r) 205 { 206 hou(root[a1],x); 207 return; 208 } 209 int mid=(l+r)>>1; 210 if(l1<=mid) 211 xihou(a1*2,l,mid,l1,r1,x); 212 if(r1>mid) 213 xihou(a1*2+1,mid+1,r,l1,r1,x); 214 return; 215 } 216 int main() 217 { 218 scanf("%d%d",&n,&m); 219 for(int i=1;i<=n;i++) 220 scanf("%d",&b[i]); 221 for(int i=1;i<=n;i++) 222 build(1,1,n,i,b[i]); 223 for(int i=0;i<m;i++) 224 { 225 int a1,a2,a3,a4; 226 scanf("%d%d%d",&a1,&a2,&a3); 227 if(a1==1) 228 { 229 scanf("%d",&a4); 230 ans=1; 231 xicha1(1,1,n,a2,a3,a4); 232 printf("%d ",ans); 233 } 234 if(a1==2) 235 { 236 scanf("%d",&a4); 237 xicha2(a2,a3,a4); 238 } 239 if(a1==3) 240 { 241 change(1,1,n,a2,a3,b[a2]); 242 b[a2]=a3; 243 } 244 if(a1==4) 245 { 246 ans=0; 247 scanf("%d",&a4); 248 xiqian(1,1,n,a2,a3,a4); 249 printf("%d ",ans); 250 } 251 if(a1==5) 252 { 253 scanf("%d",&a4); 254 ans=100000000; 255 xihou(1,1,n,a2,a3,a4); 256 printf("%d ",ans); 257 } 258 } 259 return 0; 260 }
却是是二逼平衡树。