bzoj3196 二逼平衡树

题目链接

平衡树系列最后一题

坑啊

10s时间限制跑了9764ms。。。还是要学一学bit套主席树啦。。。

经典的线段树套treap。。。至于第一发为什么要TLE(我不会告诉你treap插入的时候忘了旋转 WOC)

自认为treap写的挺好看的(欢迎来喷)

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<string>
  7 #include<cmath>
  8 #include<ctime>
  9 #include<queue>
 10 #include<stack>
 11 #include<map>
 12 #include<set>
 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 15 #define Clear(a,b) memset(a,b,sizeof(a))
 16 #define inout(x) printf("%d",(x))
 17 #define douin(x) scanf("%lf",&x)
 18 #define strin(x) scanf("%s",(x))
 19 #define LLin(x) scanf("%lld",&x)
 20 #define op operator
 21 #define CSC main
 22 typedef unsigned long long ULL;
 23 typedef const int cint;
 24 typedef long long LL;
 25 using namespace std;
 26 cint inf=100000000;
 27 void inin(int &ret)
 28 {
 29     ret=0;int f=0;char ch=getchar();
 30     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
 31     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
 32     ret=f?-ret:ret;
 33 }
 34 int ch[2000050][2],c[2000050],s[2000050],rr[2000050],w[2000020],ed;
 35 struct segtree
 36 {
 37         int l,r,root;
 38         segtree(){root=0;}
 39         void maintain(int k){if(k)s[k]=c[k]+s[ch[k][0]]+s[ch[k][1]];}
 40         void rotate(int &k,int d)
 41         {
 42             int p=ch[k][d^1];
 43             ch[k][d^1]=ch[p][d];
 44             ch[p][d]=k;s[p]=s[k];
 45             maintain(k),k=p;
 46         }
 47     private:
 48         void add(int &k,const int &x)
 49         {
 50             if(!k)
 51             {
 52                 k=++ed,w[k]=x,rr[k]=rand();s[k]=c[k]=1;ch[k][0]=ch[k][1]=0;
 53                 return ;
 54             }s[k]++;
 55             if(x==w[k]){c[k]++;return ;}
 56             int d=x>w[k];add(ch[k][d],x);
 57             if(rr[ch[k][d]]<rr[k])rotate(k,d^1);
 58         }
 59         bool del(int &k,const int &x)
 60         {
 61             if(!k)return 0;
 62             if(x==w[k])
 63             {
 64                 if(c[k]>1){c[k]--,s[k]--;return 1;}
 65                 if(!ch[k][0]){k=ch[k][1];return 1;}
 66                 if(!ch[k][1]){k=ch[k][0];return 1;}
 67                 if(rr[ch[k][0]]<rr[ch[k][1]])rotate(k,1);
 68                 else rotate(k,0);
 69                 return del(k,x);
 70             }
 71             int d=x>w[k];
 72             if(del(ch[k][d],x))
 73             {
 74                 s[k]--;
 75                 return 1;
 76             }
 77             else return 0;
 78         }
 79         int findrank(int k,const int &x)
 80         {
 81             if(!k)return 0;
 82             int pp=(ch[k][0]?s[ch[k][0]]:0);
 83             if(x==w[k])return pp;
 84             if(x>w[k])return pp+c[k]+findrank(ch[k][1],x);
 85             return findrank(ch[k][0],x);
 86         }
 87         int findwei(int k,const int &x)
 88         {
 89             if(!k)return 0;
 90             int pp=(ch[k][0]?s[ch[k][0]]:0);
 91             if(x<=pp)return findwei(ch[k][0],x);
 92             if(x>pp+c[k])return findwei(ch[k][1],x-pp-c[k]);
 93             return w[k];
 94         
 95         }
 96         void findqian(int k,const int &x,int &ans)
 97         {
 98             if(!k)return ;
 99             if(x>w[k])ans=w[k],findqian(ch[k][1],x,ans);
100             else findqian(ch[k][0],x,ans);
101         }
102         void findhou(int k,const int &x,int &ans)
103         {
104             if(!k)return ;
105             if(x<w[k])ans=w[k],findhou(ch[k][0],x,ans);
106             else findhou(ch[k][1],x,ans);
107         }
108     public:
109         void add(int x){add(root,x);}
110         void del(int x){del(root,x);}
111         int findrank(int x){return findrank(root,x);}
112         int findwei(int x){return findwei(root,x);}
113         int findqian(int x)
114         {
115             int ans=0;findqian(root,x,ans);
116             return ans;
117         }
118         int findhou(int x)
119         {
120             int ans=0;findhou(root,x,ans);
121             return !ans?inf:ans;
122         }
123 }t[200020];
124 int qi[50050];
125 void build(int k,int l,int r,int x)
126 {
127     t[k].l=l,t[k].r=r,t[k].add(qi[x]);
128     if(l==r)return ;int mid=(l+r)>>1;
129     if(x<=mid)build(k<<1,l,mid,x);
130     else build(k<<1|1,mid+1,r,x);
131 }
132 int findrank(int k,int l,int r,int x)
133 {
134     if(t[k].l>=l&&t[k].r<=r)return t[k].findrank(x);
135     int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;
136     if(r<=mid)return findrank(p1,l,r,x);
137     if(l>mid)return findrank(p2,l,r,x);
138     return findrank(p1,l,r,x)+findrank(p2,l,r,x);
139 }
140 int findqian(int k,int l,int r,int x)
141 {
142     if(t[k].l>=l&&t[k].r<=r)return t[k].findqian(x);
143     int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;
144     if(r<=mid)return findqian(p1,l,r,x);
145     if(l>mid)return findqian(p2,l,r,x);
146     return max(findqian(p1,l,r,x),findqian(p2,l,r,x));
147 }
148 int findhou(int k,int l,int r,int x)
149 {
150     if(t[k].l>=l&&t[k].r<=r)return t[k].findhou(x);
151     int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;
152     if(r<=mid)return findhou(p1,l,r,x);
153     if(l>mid)return findhou(p2,l,r,x);
154     return min(findhou(p1,l,r,x),findhou(p2,l,r,x));
155 }
156 int findwei(int l,int r,int x)
157 {
158     int ll=0,rr=inf,mid,ans;
159     while(ll<=rr)
160     {
161         mid=(ll+rr)>>1;
162         int rank=findrank(1,l,r,mid)+1;
163         if(rank<=x)ans=mid,ll=mid+1;else rr=mid-1;
164     }
165     return findqian(1,l,r,ans+1);
166 }
167 void change(int k,int x,int w)
168 {
169     t[k].del(qi[x]),t[k].add(w);
170     if(t[k].l==t[k].r)return ;
171     int mid=(t[k].l+t[k].r)>>1;
172     if(x<=mid)change(k<<1,x,w);
173     else change(k<<1|1,x,w);
174 }
175 int n,m;
176 int CSC()
177 {
178     freopen("in.in","r",stdin);
179     freopen("out.out","w",stdout);
180     inin(n),inin(m);
181     re(i,1,n)inin(qi[i]);
182     re(i,1,n)build(1,1,n,i);
183     re(i,1,m)
184     {
185         int opt,q,ww,e;
186         inin(opt);
187         if(opt==1)
188         {
189             inin(q),inin(ww),inin(e);
190             printf("%d\n",findrank(1,q,ww,e)+1);
191         }
192         else if(opt==2)
193         {
194             inin(q),inin(ww),inin(e);
195             printf("%d\n",findwei(q,ww,e));
196         }
197         else if(opt==3)
198         {
199             inin(q),inin(ww);
200             change(1,q,ww);qi[q]=ww;
201         }
202         else if(opt==4)
203         {
204             inin(q),inin(ww),inin(e);
205             printf("%d\n",findqian(1,q,ww,e));
206         }
207         else 
208         {
209             inin(q),inin(ww),inin(e);int ret=findhou(1,q,ww,e);
210 //            printf("%d\n",ret==inf?0:ret);
211             printf("%d\n",ret);
212         }
213     }
214     return 0;
215 }

 

转载于:https://www.cnblogs.com/HugeGun/p/5150875.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值