BZOJ - 3196 Tyvj 1730 二逼平衡树 (线段树套treap)
区间线段树套treap,空间复杂度$O(nlogn)$,时间复杂度除了查询区间k大是$O(log^3n)$以外都是$O(log^2n)$的。
(据说线段树套线段树、树状数组套线段树也能过?)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=5e4+10,inf=0x3f3f3f3f; 5 #define lson (u<<1) 6 #define rson (u<<1|1) 7 #define mid ((l+r)>>1) 8 int n,m,a[N],rt[N<<2],ch[N*40][2],val[N*40],siz[N*40],rd[N*40],tot; 9 void pu(int u) {siz[u]=siz[ch[u][0]]+siz[ch[u][1]]+1;} 10 int newnode(int x) {int u=++tot; val[u]=x,siz[u]=1,ch[u][0]=ch[u][1]=0,rd[u]=rand(); return u;} 11 void rot(int& u,int f) { 12 int v=ch[u][f]; 13 ch[u][f]=ch[v][f^1],ch[v][f^1]=u; 14 pu(u),pu(v),u=v; 15 } 16 void ins(int& u,int x) { 17 if(!u) {u=newnode(x); return;} 18 int f=x>val[u]; 19 ins(ch[u][f],x); 20 if(rd[ch[u][f]]>rd[u])rot(u,f); 21 if(u)pu(u); 22 } 23 void del(int& u,int x) { 24 if(!u)return; 25 if(val[u]==x) { 26 if(!ch[u][0]||!ch[u][1])u=ch[u][0]|ch[u][1]; 27 else { 28 int f=rd[ch[u][1]]>rd[ch[u][0]]; 29 rot(u,f),del(ch[u][f^1],x); 30 } 31 } else del(ch[u][x>val[u]],x); 32 if(u)pu(u); 33 } 34 int rnk(int u,int x) { 35 int ret=0; 36 for(; u; u=ch[u][x>val[u]])if(x>val[u])ret+=siz[ch[u][0]]+1; 37 return ret+1; 38 } 39 int kth(int u,int k) { 40 while(k!=siz[ch[u][0]]+1) { 41 if(k<siz[ch[u][0]]+1)u=ch[u][0]; 42 else k-=siz[ch[u][0]]+1,u=ch[u][1]; 43 } 44 return val[u]; 45 } 46 int lb(int u,int x) { 47 int ret=0; 48 for(; u; u=ch[u][x>val[u]])if(val[u]<x)ret=val[u]; 49 return ret; 50 } 51 int ub(int u,int x) { 52 int ret=0; 53 for(; u; u=ch[u][x>=val[u]])if(val[u]>x)ret=val[u]; 54 return ret; 55 } 56 void upd(int p,int x,int u=1,int l=1,int r=n) { 57 del(rt[u],a[p]),ins(rt[u],x); 58 if(l==r)return; 59 p<=mid?upd(p,x,lson,l,mid):upd(p,x,rson,mid+1,r); 60 } 61 void build(int u=1,int l=1,int r=n) { 62 for(int i=l; i<=r; ++i)ins(rt[u],a[i]); 63 if(l==r)return; 64 build(lson,l,mid),build(rson,mid+1,r); 65 } 66 int qry1(int L,int R,int x,int u=1,int l=1,int r=n) { 67 if(l>=L&&r<=R) {return rnk(rt[u],x)-1;} 68 if(l>R||r<L)return 0; 69 return qry1(L,R,x,lson,l,mid)+qry1(L,R,x,rson,mid+1,r); 70 } 71 int qry2(int L,int R,int k) { 72 int l=0,r=inf; 73 while(l<r)qry1(L,R,mid+1)>=k?r=mid:l=mid+1; 74 return l; 75 } 76 int qry4(int L,int R,int x,int u=1,int l=1,int r=n) { 77 if(l>=L&&r<=R) {int t=lb(rt[u],x); return t?t:~inf;} 78 if(l>R||r<L)return ~inf; 79 return max(qry4(L,R,x,lson,l,mid),qry4(L,R,x,rson,mid+1,r)); 80 } 81 int qry5(int L,int R,int x,int u=1,int l=1,int r=n) { 82 if(l>=L&&r<=R) {int t=ub(rt[u],x); return t?t:inf;} 83 if(l>R||r<L)return inf; 84 return min(qry5(L,R,x,lson,l,mid),qry5(L,R,x,rson,mid+1,r)); 85 } 86 int main() { 87 srand(time(0)); 88 scanf("%d%d",&n,&m); 89 for(int i=1; i<=n; ++i)scanf("%d",&a[i]); 90 build(); 91 while(m--) { 92 int f,l,r,x; 93 scanf("%d",&f); 94 if(f==1)scanf("%d%d%d",&l,&r,&x),printf("%d\n",qry1(l,r,x)+1); 95 else if(f==2)scanf("%d%d%d",&l,&r,&x),printf("%d\n",qry2(l,r,x)); 96 else if(f==3)scanf("%d%d",&l,&x),upd(l,x),a[l]=x; 97 else if(f==4)scanf("%d%d%d",&l,&r,&x),printf("%d\n",qry4(l,r,x)); 98 else if(f==5)scanf("%d%d%d",&l,&r,&x),printf("%d\n",qry5(l,r,x)); 99 } 100 return 0; 101 }