bzoj 3196: Tyvj 1730 二逼平衡树

  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\n",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\n",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\n",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\n",ans);
257             }
258       }
259    return 0;
260 }

却是是二逼平衡树。

转载于:https://www.cnblogs.com/xydddd/p/5309138.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值