树套树-线段树套平衡树

树套树-线段树套平衡树

这个代码写起来真心累。。。

今天反正是不想再写一遍了

虽然好像十分无脑的样子。。。

思路十分简单,实现十分自然。。。

bzoj 3196 二逼平衡树

#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)

ll read(){
    ll x=0,f=1;char c=getchar();
    while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

#define lc (i<<1)
#define rc (i<<1|1)
const int maxn=50050;
struct Node{
    int l,r,root;
} tr[maxn*3];
int n,m,a[maxn],b[maxn],tot;
struct TreapNode{
    int ls,rs,val,rnd,sz;
} treap[maxn*20];
int sta[maxn],top;

int newnode(int v){
    treap[++tot].val=v;treap[tot].rnd=rand();
    treap[tot].sz=1;treap[tot].ls=treap[tot].rs=0;
    return tot;
}
void update(int i){
    treap[i].sz=treap[treap[i].ls].sz+treap[treap[i].rs].sz+1;
}
void build(int i,int l,int r){
    tr[i].l=l,tr[i].r=r;
    if(l==r){
        tr[i].root=newnode(a[l]);
        return;
    }
    rep(k,l,r) b[k]=a[k];
    sort(b+l,b+r+1);
    int nw=0,pre=0;top=0;
    rep(k,l,r){
        nw=newnode(b[k]);pre=0;
        while(top && treap[sta[top]].rnd>treap[nw].rnd){
            update(sta[top]);
            pre=sta[top];
            sta[top--]=0;
        }
        if(top) treap[sta[top]].rs=nw;
        treap[nw].ls=pre;sta[++top]=nw;
    }
    while(top) update(sta[top--]);
    tr[i].root=sta[1];
    int md=(l+r)>>1;
    build(lc,l,md);build(rc,md+1,r);
}
void split(int &x,int &y,int val,int nw){
    if(nw==0){x=y=0;return;}
    if(treap[nw].val<=val){
        x=nw;split(treap[x].rs,y,val,treap[x].rs);
    }
    else{
        y=nw;split(x,treap[y].ls,val,treap[y].ls);
    }
    update(nw);
}
int merge(int x,int y){
    if(!x || !y) return x+y;
    int nw;
    if(treap[x].rnd<treap[y].rnd){
        treap[x].rs=merge(treap[x].rs,y);
        update(x);return x;
    }
    else{
        treap[y].ls=merge(x,treap[y].ls);
        update(y);return y;
    }
}
int fnd1(int i,int v){
    int x,y;
    split(x,y,v-1,tr[i].root);
    int ret=treap[x].sz;
    //cerr<<treap[x].val<<' '<<treap[treap[x].ls].val<<' '<<treap[x].ls<<' '<<treap[x].rs<<endl;
    tr[i].root=merge(x,y);return ret;
}
int ask1(int i,int l,int r,int L,int R,int v){
    if(l>=L && r<=R){
        int ret=fnd1(i,v);
    //  cerr<<l<<' '<<r<<' '<<ret<<endl;
        return ret;
    }
    if(l>R || r<L) return 0;
    int md=(l+r)>>1;
    return ask1(lc,l,md,L,R,v)+ask1(rc,md+1,r,L,R,v);
}
int query1(int l,int r,int k){
    int ret=ask1(1,1,n,l,r,k)+1;
    //cerr<<l<<' '<<r<<' '<<k<<' '<<ret<<endl;
    return ret;
}
int query2(int l,int r,int k){
    int L=0,R=100000000;
    while(L+1<R){
        int md=(L+R)>>1;
        int num=query1(l,r,md);
        if(num<=k) L=md;
        else R=md-1;
    //  cout<<md<<"is"<<num<<endl;
    }
    int num=query1(l,r,L+1);
    if(num<=k) return L+1;
    else return L;
}
void modify(int i,int l,int r,int pos,int v1,int v2){
    int x,y,z;
    split(x,z,v2,tr[i].root);
    split(x,y,v2-1,x);
    y=merge(treap[y].ls,treap[y].rs);
    tr[i].root=merge(merge(x,y),z);
    split(x,y,v1,tr[i].root);
    tr[i].root=merge(merge(x,newnode(v1)),y);
    if(l==r) return;
    int md=(l+r)>>1;
    if(pos<=md) modify(lc,l,md,pos,v1,v2);
    else modify(rc,md+1,r,pos,v1,v2);
}
void change(int pos,int v1,int v2){
    modify(1,1,n,pos,v1,v2);
}
int fnd4(int i,int v){
    int nw=tr[i].root,x,y;
    split(x,y,v-1,nw);
    int nod=x;
    while(treap[nod].rs) nod=treap[nod].rs;
    int ret=treap[nod].val;
    tr[i].root=merge(x,y);
    return ret;
}
int ask4(int i,int l,int r,int L,int R,int v){
    if(l>=L && r<=R) return fnd4(i,v);
    if(l>R || r<L) return -1e9;
    int md=(l+r)>>1;
    return max(ask4(lc,l,md,L,R,v),ask4(rc,md+1,r,L,R,v));
}
int query4(int l,int r,int k){
    return ask4(1,1,n,l,r,k);
}
int fnd5(int i,int v){
    int nw=tr[i].root,x,y;
    split(x,y,v,nw);
    int nod=y;
    while(treap[nod].ls) nod=treap[nod].ls;
    int ret=treap[nod].val;if(nod==0) ret=1e9;
    tr[i].root=merge(x,y);
    return ret;
}
int ask5(int i,int l,int r,int L,int R,int v){
    if(l>=L && r<=R) return fnd5(i,v);
    if(l>R || r<L) return 1e9;
    int md=(l+r)>>1;
    return min(ask5(lc,l,md,L,R,v),ask5(rc,md+1,r,L,R,v));
}
int query5(int l,int r,int k){
    return ask5(1,1,n,l,r,k);
}
int main(){
    srand(20020709);
    //freopen("in","r",stdin);
    n=read(),m=read();
    rep(i,1,n) a[i]=read();
    build(1,1,n);
    while(m--){
        int op=read();
        if(op==1){
            int l=read(),r=read(),k=read();
            printf("%d\n",query1(l,r,k));
        }
        else if(op==2){
            int l=read(),r=read(),k=read();
            printf("%d\n",query2(l,r,k));
        }
        else if(op==3){
            int pos=read(),v=read();
            change(pos,v,a[pos]);
            a[pos]=v;
        }
        else if(op==4){
            int l=read(),r=read(),k=read();
            printf("%d\n",query4(l,r,k));
        }
        else{
            int l=read(),r=read(),k=read();
            printf("%d\n",query5(l,r,k));
        }
    }
    return 0;
}

/*
9 6
4 2 2 1 9 4 0 1 1
2 1 4 3
3 4 10
2 1 4 3
1 2 5 9
4 3 9 5
5 2 8 5
*/

猜你喜欢

转载自www.cnblogs.com/wawawa8/p/9664171.html