树套树-线段树套平衡树

树套树-线段树套平衡树

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

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

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

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

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
*/
posted @ 2018-09-17 18:53  wawawa8  阅读(364)  评论(1编辑  收藏  举报