码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 3196: Tyvj 1730 二逼平衡树

时间:2017-02-28 22:17:21      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:oid   namespace   root   code   printf   lin   change   getc   span   

我操,,,,我记得这个sb题,,搞了一整天,(吐槽,本来开心去洛谷提交,结果不一样,mdzz)

树套树,,,各种套。。。

都是在区间内最基本的查询

  1 #include<bits/stdc++.h>
  2 #define N 100005
  3 #define LL long long
  4 #define inf 0x3f3f3f3f
  5 using namespace std;
  6 inline int ra()
  7 {
  8     int x=0,f=1; char ch=getchar();
  9     while (ch<0 || ch>9) {if (ch==-) f=-1; ch=getchar();}
 10     while (ch>=0 && ch<=9) {x=x*10+ch-0; ch=getchar();}
 11     return x*f;
 12 }
 13 const int M=3000001;
 14 int a[N],pre,tmp,nxt,n,m,sz;
 15 int rnd[M],ls[M],rs[M],s[M],v[M],w[M],root[M];
 16 void update(int k){s[k]=s[ls[k]]+s[rs[k]]+w[k];}
 17 void rturn(int &k){int t=ls[k]; ls[k]=rs[t]; rs[t]=k; s[t]=s[k]; update(k); k=t;}
 18 void lturn(int &k){int t=rs[k]; rs[k]=ls[t]; ls[t]=k; s[t]=s[k]; update(k); k=t;}
 19 void insert(int &k, int num)
 20 {
 21     if (!k){
 22         k=++sz; s[k]=w[k]=1; ls[k]=rs[k]=0; v[k]=num; rnd[k]=rand(); return;
 23     }
 24     s[k]++;
 25     if (v[k]==num) w[k]++;
 26     else if (v[k]>num) {insert(ls[k],num); if (rnd[ls[k]]<rnd[k]) rturn(k);}
 27     else {insert(rs[k],num); if (rnd[rs[k]]<rnd[k]) lturn(k);}
 28 }
 29 void del(int &k, int num)
 30 {
 31     if (v[k]==num)
 32     {
 33         if (w[k]>1) {w[k]--,s[k]--; return;}
 34         else{
 35             if (ls[k]*rs[k]==0) k=ls[k]+rs[k];
 36             else if (rnd[ls[k]]<rnd[rs[k]]) rturn(k),del(k,num);
 37             else lturn(k),del(k,num);
 38         }
 39     }
 40     else if (v[k]>num) del(ls[k],num),s[k]--;
 41     else del(rs[k],num),s[k]--;
 42 }
 43 void build(int k, int l, int r, int x, int num)
 44 {
 45     insert(root[k],num);
 46     if (l==r) return;
 47     int mid=l+r>>1;
 48     if (x<=mid) build(k<<1,l,mid,x,num);
 49     else build(k<<1|1,mid+1,r,x,num);
 50 }
 51 void find_min(int k, int num)
 52 {
 53     if (!k) return;
 54     if (num==v[k]) {tmp+=s[ls[k]]; return;}
 55     else if (num<v[k]) find_min(ls[k],num);
 56     else tmp+=s[ls[k]]+w[k],find_min(rs[k],num); 
 57 }
 58 void askrank_min(int k, int l, int r, int x, int y, int num)
 59 {
 60     if (l==x && y==r) {find_min(root[k],num);return;}
 61     int mid=l+r>>1;
 62     if (y<=mid) askrank_min(k<<1,l,mid,x,y,num);
 63     else if (x>mid) askrank_min(k<<1|1,mid+1,r,x,y,num);
 64     else askrank_min(k<<1,l,mid,x,mid,num),askrank_min(k<<1|1,mid+1,r,mid+1,y,num);
 65 }
 66 void change(int k, int l, int r, int pos, int old, int num)
 67 {
 68     del(root[k],old); insert(root[k],num);
 69     if (l==r) return;
 70     int mid=l+r>>1;
 71     if (pos<=mid) change(k<<1,l,mid,pos,old,num);
 72     else change(k<<1|1,mid+1,r,pos,old,num);
 73 }
 74 void findpre(int k, int num)
 75 {
 76     if (!k) return;
 77     if (v[k]>=num) findpre(ls[k],num);
 78     else pre=max(pre,v[k]), findpre(rs[k],num);
 79 }
 80 void getpre(int k, int l, int r, int x, int y, int num)
 81 {
 82     if (l==x && y==r) {findpre(root[k],num);return;}
 83     int mid=l+r>>1;
 84     if (y<=mid) getpre(k<<1,l,mid,x,y,num);
 85     else if (x>mid) getpre(k<<1|1,mid+1,r,x,y,num);
 86     else getpre(k<<1,l,mid,x,mid,num),getpre(k<<1|1,mid+1,r,mid+1,y,num);
 87 }
 88 void findnxt(int k, int num)
 89 {
 90     if (!k) return;
 91     if (v[k]<=num) findnxt(rs[k],num);
 92     else nxt=min(nxt,v[k]),findnxt(ls[k],num);
 93 }
 94 void getnxt(int k, int l, int r, int x, int y, int num)
 95 {
 96     if (l==x && y==r) {findnxt(root[k],num);return;}
 97     int mid=l+r>>1;
 98     if (y<=mid) getnxt(k<<1,l,mid,x,y,num);
 99     else if (x>mid) getnxt(k<<1|1,mid+1,r,x,y,num);
100     else getnxt(k<<1,l,mid,x,mid,num),getnxt(k<<1|1,mid+1,r,mid+1,y,num);
101 }
102 int main()
103 {
104     n=ra(); m=ra();
105     for (int i=1; i<=n; i++) a[i]=ra();
106     for (int i=1; i<=n; i++) build(1,1,n,i,a[i]);
107     while (m--)
108     {
109         int opt=ra();
110         if (opt==1)
111         {
112             int l=ra(),r=ra(),k=ra(); tmp=1;
113             askrank_min(1,1,n,l,r,k);
114             printf("%d\n",tmp);
115         }
116         if (opt==2)
117         {
118             int l=ra(),r=ra(),k=ra();
119             int x=0,y=1000000005,ans;
120             while (x<=y)
121             {
122                 int mid=x+y>>1;
123                 tmp=1; askrank_min(1,1,n,l,r,mid);
124                 if (tmp<=k) x=mid+1,ans=mid; else y=mid-1; 
125             }
126             printf("%d\n",ans);
127         }
128         if (opt==3)
129         {
130             int pos=ra(),k=ra();
131             change(1,1,n,pos,a[pos],k);
132             a[pos]=k;
133         }
134         if (opt==4)
135         {
136             int l=ra(),r=ra(),k=ra(); pre=-inf;
137             getpre(1,1,n,l,r,k);
138             printf("%d\n",pre);
139         }
140         if (opt==5)
141         {
142             int l=ra(),r=ra(),k=ra();
143             nxt=inf; 
144             getnxt(1,1,n,l,r,k);
145             printf("%d\n",nxt);
146         }
147     //    system("pause");
148     }
149     return 0;
150 }

 

bzoj 3196: Tyvj 1730 二逼平衡树

标签:oid   namespace   root   code   printf   lin   change   getc   span   

原文地址:http://www.cnblogs.com/ccd2333/p/6481030.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!