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 }

 

posted @ 2019-04-11 20:00  jrltx  阅读(190)  评论(0编辑  收藏  举报