[Template] two forced balanced tree (balanced tree segment tree +)

Title Description

You need to write a data structure (refer to the subject of the title), to maintain an orderly sequence, which need to provide the following:

1. k ranking queries within range

 

2. Query ranked within the range of values ​​of k

 

 

3. Modify the value of a bit value

 

 

4. Query interval k in the precursor (precursor strictly defined as less than x, and the maximum number, if there -2147483647 output)

 

5. Query k in the subsequent interval (defined as successor strictly greater than x, and the smallest number, output if there 2147483647)

n- , m . 5 . 1 0 . 4  to ensure that all the values in the ordered sequence satisfies any time [ 0 , . 1 0 . 8 ]

answer

These operations are common actions balance the tree, consider how maintenance intervals.

With a segment tree can, for the construction of a line segment sequence tree, each node maintains a splay, splay maintenance interval numbers.

1. As soon as the query how he can be smaller than the range of a few

2. not directly query, they can only recall two scores is the number 1 judge

3. delete and insert on a chain

4. Take max among all of the precursor cells found out

5. Remove min for all subsequent check out

The function code is written a bit more, very hard to accept, but still only in accordance with their own ideas to add

#include<bits/stdc++.h>
using namespace std;
const int maxn=50005;
const int maxm=2000005;
const int oo=2147483647;
int n,m,o,cnt,num,ls[maxn<<1],rs[maxn<<1];
int a[maxn];
int root[maxn<<1];
struct Splay{
    int fa,s[2],size,tag;
    int val;
}tr[maxm];

template<class T>inline void read(T &x){
    x=0;char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
}

void update(int x){
    tr[x].size=tr[tr[x].s[0]].size+tr[tr[x].s[1]].size+tr[x].tag;
}

int get(int x){
    return tr[tr[x].fa].s[1]==x;
}

void connect(int x,int y,int d){
    tr[x].fa=y;
    tr[y].s[d]=x;
}

void rotate(int x){
    int f=tr[x].fa,ff=tr[f].fa;
    int d1=get(x),d2=get(f);
    int cs=tr[x].s[d1^1];
    connect(x,ff,d2);
    connect(f,x,d1^1);
    connect(cs,f,d1);
    update(f);
    update(x);
}

void splay(int x,int go,int id){
    if(go==root[id]) root[id]=x;
    go=tr[go].fa;
    while(tr[x].fa!=go){
        int f=tr[x].fa;
        if(tr[f].fa==go) rotate(x);
        else if(get(f)==get(x)) {rotate(f);rotate(x);}
        else {rotate(x);rotate(x);}
    }
}

void insert(int val,int id){
    int now=root[id];
    if(!now){
        root[id]=++num;
        tr[num]=(Splay){0,{0,0},1,1,val};
        return ;
    }
    while(now){
        tr[now].size++;
        if(tr[now].val==val){
            tr[now].tag++;
            break;
        }
        int d=val>tr[now].val;
        if(!tr[now].s[d]){
            tr[now].s[d]=++num;
            tr[num]=(Splay){now,{0,0},1,1,val};
            now=num;
            break;
        }
        now=tr[now].s[d];
    }
    splay(now,root[id],id);
}

void modify(int &rt,int l,int r,int pos,int val){
    if(!rt) {
        rt=++cnt;
        insert(oo,rt);
        insert(-oo,rt);
    }
    insert(val,rt);
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(pos<=mid) modify(ls[rt],l,mid,pos,val);
    else modify(rs[rt],mid+1,r,pos,val);
}

int query(int id,int val){
    int now=root[id],ret=0;
    while(now){
        if(tr[now].val==val) return ret+tr[tr[now].s[0]].size;
        else if(tr[now].val<val){
            ret+=tr[tr[now].s[0]].size+tr[now].tag;
            now=tr[now].s[1];
        }
        else now=tr[now].s[0];
    }
    return ret;
}

int seq_queryrank(int rt,int l,int r,int a_l,int a_r,int val){
    if(a_l<=l&&r<=a_r) return query(rt,val)-1;
    int ret=0,mid=(l+r)>>1;
    if(a_l<=mid) ret+=seq_queryrank(ls[rt],l,mid,a_l,a_r,val);
    if(mid<a_r) ret+=seq_queryrank(rs[rt],mid+1,r,a_l,a_r,val);
    return ret;
}

int querynumber(int l,int r,int k){
    int L=0,R=oo,ret;
    while(L<=R){
        int mid=(L+R)>>1;
        if(seq_queryrank(1,1,n,l,r,mid)+1<=k) ret=mid,L=mid+1;
        else R=mid-. 1 ; 
    } 
    return RET; 
} 

int findval ( int ID, int Val) { // find the value of x which 
    int now = the root [ID];
     the while ( . 1 ) {
         IF (TR [now] .val == Val ) return now;
         the else  IF (TR [now] .val <Val) now TR = [now] .s [ . 1 ];
         the else now TR = [now] .s [ 0 ]; 
    } 
} 

int findrank ( int ID, int k) { // Find x which is ranked 
    int now=root[id];
    while(1){
        if(tr[tr[now].s[0]].size>=k) {now=tr[now].s[0];continue;}
        k-=tr[tr[now].s[0]].size;
        if(k<=tr[now].tag) return now;
        k-=tr[now].tag;
        now=tr[now].s[1];
    }
}

void dele(int id,int val){
    int now=findval(id,val);
    splay(now,root[id],id);
    if(tr[now].tag>1) {tr[now].tag--;tr[now].size--;return ;}
    int  k=tr[tr[now].s[0]].size,x=findrank(id,k),y=findrank(id,k+tr[now].tag+1);
    splay(x,root[id],id);
    splay(y,tr[x].s[1],id);
    tr[y].s[0]=0;
    update(y);update(x);
}

void get_dele(int rt,int l,int r,int pos,int val){
    dele(rt,val);
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(pos<=mid) get_dele(ls[rt],l,mid,pos,val);
    else get_dele(rs[rt],mid+1,r,pos,val);
}

int querypre(int id,int val){
    int now=root[id],ans=-oo;
    while(now){
        if(tr[now].val<val){
            ans=max(ans,tr[now].val);
            now=tr[now].s[1];
        }
        else now=tr[now].s[0];
    }
    return ans;
}

int seg_querypre(int rt,int l,int r,int a_l,int a_r,int val){
    if(a_l<=l&&r<=a_r) return querypre(rt,val);
    int ans=-oo,mid=(l+r)>>1;
    if(a_l<=mid) ans=max(ans,seg_querypre(ls[rt],l,mid,a_l,a_r,val));
    if(mid<a_r) ans=max(ans,seg_querypre(rs[rt],mid+1,r,a_l,a_r,val));
    return ans;
}

int querynext(int id,int val){
    int now=root[id],ans=oo;
    while(now){
        if(tr[now].val>val){
            ans=min(ans,tr[now].val);
            now=tr[now].s[0];
        }
        else now=tr[now].s[1];
    }
    return ans;
}

int seg_querynext(int rt,int l,int r,int a_l,int a_r,int val){
    if(a_l<=l&&r<=a_r) return querynext(rt,val);
    int ans=oo,mid=(l+r)>>1;
    if(a_l<=mid) ans=min(ans,seg_querynext(ls[rt],l,mid,a_l,a_r,val));
    if(mid<a_r) ans=min(ans,seg_querynext(rs[rt],mid+1,r,a_l,a_r,val));
    return ans;
}

void debug(int x){
    if(tr[x].s[0]) debug(tr[x].s[0]);;
    printf("%d ",tr[x].val);
    if(tr[x].s[1]) debug(tr[x].s[1]);
}

int main(){
    read(n);read(m);
    for(int i=1;i<=n;i++){
        read(a[i]);
        modify(o,1,n,i,a[i]);
    }
    for(int i=1;i<=m;i++){
        int opt;read(opt);
        if(opt==1){
            int l,r,val;
            read(l);read(r);read(val);
            printf("%d\n",seq_queryrank(1,1,n,l,r,val)+1); 
        }
        else if(opt==2){
            int l,r,k;
            read(l);read(r);read(k);
            printf("%d\n",querynumber(l,r,k));
        }
        else if(opt==3){
            int pos,val;
            read(pos);read(val);
            get_dele(1,1,n,pos,a[pos]);
            modify(o,1,n,pos,a[pos]=val);
        }
        else if(opt==4){
            int l,r,val;
            read(l);read(r);read(val);
            printf("%d\n",seg_querypre(1,1,n,l,r,val));
        }
        else {
            int l,r,val;
            read(l);read(r);read(val);
            printf("%d\n",seg_querynext(1,1,n,l,r,val));
        }
    }
}
[Template] two forced balanced tree (tree cover tree)

 

Guess you like

Origin www.cnblogs.com/sto324/p/11409389.html