BZOJ 3196 线段树套平衡树
2016-12-05 00:34
253 查看
(代码无比丑陋)
//By SiriusRen #include <cstdio> #include <algorithm> using namespace std; int n,m,L,R,xx,tx,t,root[3000050],size,ans,op,inf=0x3fffffff,a[500050]; struct Treap{int ch[2],v,cnt,sz,rnd;}tr[3000050]; void Upd(int k){tr[k].sz=tr[tr[k].ch[0]].sz+tr[tr[k].ch[1]].sz+tr[k].cnt;} void rot(int &k,bool f){int t=tr[k].ch[f];tr[k].ch[f]=tr[t].ch[!f],tr[t].ch[!f]=k,Upd(k),Upd(t),k=t;} void ins(int &k){ if(!k){k=++size;tr[k].v=xx;tr[k].cnt=tr[k].sz=1;tr[k].rnd=rand();return;} tr[k].sz++; if(tr[k].v==xx){tr[k].cnt++;return;} bool f=xx>tr[k].v;ins(tr[k].ch[f]); if(tr[tr[k].ch[f]].rnd<tr[k].rnd)rot(k,f); } void del(int &k){ if(tr[k].v==tx){ if(tr[k].cnt>1)tr[k].cnt--,tr[k].sz--; else if(tr[k].ch[0]*tr[k].ch[1]==0)k=tr[k].ch[0]+tr[k].ch[1]; else rot(k,tr[tr[k].ch[0]].rnd>=tr[tr[k].ch[1]].rnd),del(k); } else tr[k].sz--,del(tr[k].ch[tx>tr[k].v]); } void rank(int k){ if(!k)return; if(tr[k].v==xx)ans+=tr[tr[k].ch[0]].sz; else if(tr[k].v>xx)rank(tr[k].ch[0]); else ans+=tr[tr[k].ch[0]].sz+tr[k].cnt,rank(tr[k].ch[1]); } void query(int k){ if(!k)return; if(op==4&&tr[k].v<xx)ans=max(ans,tr[k].v),query(tr[k].ch[1]); else if(op==4)query(tr[k].ch[0]); else if(op==5&&tr[k].v>xx)ans=min(ans,tr[k].v),query(tr[k].ch[0]); else query(tr[k].ch[1]); } void Build(int l,int r,int pos){ ins(root[pos]);if(l==r)return; int mid=(l+r)>>1; if(mid<t)Build(mid+1,r,pos<<1|1); else Build(l,mid,pos<<1); } void Rank(int l,int r,int pos){ if(l>=L&&r<=R){rank(root[pos]);return;} int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1; if(mid<L)Rank(mid+1,r,rson); else if(mid>=R)Rank(l,mid,lson); else Rank(l,mid,lson),Rank(mid+1,r,rson); } void Change(int l,int r,int pos){ del(root[pos]),ins(root[pos]); if(l==r)return; int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1; if(mid<t)Change(mid+1,r,rson); else Change(l,mid,lson); } void Ask(int l,int r,int pos){ if(l>=L&&r<=R){query(root[pos]);return;} int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1; if(mid<L)Ask(mid+1,r,rson); else if(mid>=R)Ask(l,mid,lson); else Ask(l,mid,lson),Ask(mid+1,r,rson); } void b_srch(){ int l=0,r=inf,Ans=0; while(l<=r){ ans=1,xx=(l+r)>>1,Rank(1,n,1); if(ans<=tx)Ans=xx,l=xx+1; else r=xx-1; } printf("%d\n",Ans); } int main(){ scanf("%d%d",&n,&m); for(t=1;t<=n;t++)scanf("%d",&a[t]),xx=a[t],Build(1,n,1); while(m--){ scanf("%d",&op); if(op!=3){ scanf("%d%d%d",&L,&R,&xx); if(op==1)ans=1,Rank(1,n,1),printf("%d\n",ans); else if(op==2)tx=xx,b_srch(); else{ ans=inf;if(op==4)ans=0;Ask(1,n,1); printf("%d\n",ans); } } else scanf("%d%d",&t,&xx),tx=a[t],Change(1,n,1),a[t]=xx; } }
相关文章推荐
- Flex Namespace的用法
- C#中struct和class的区别详解
- 深入剖析C++中的struct结构体字节对齐
- C++ 关于STL中sort()对struct排序的方法
- C# Struct的内存布局问题解答
- ajax使用不同namespace的action的方法
- 深入C++中struct与class的区别分析
- 浅析c与c++中struct的区别
- 浅谈几种常见语言的命名空间(Namespace)
- c++中struct使用注意事项
- 深入解析C#编程中struct所定义的结构
- thinkphp autoload 命名空间自定义 namespace
- PHP命名空间(namespace)的使用基础及示例
- php中namespace use用法实例分析
- 浅析JavaScript中命名空间namespace模式
- 浅析内存对齐与ANSI C中struct型数据的内存布局
- php读取二进制流(C语言结构体struct数据文件)的深入解析
- C语言中结构体(struct)的几种初始化方法
- 详解C++程序中定义struct结构体的方法
- C++ namespace相关语法实例分析