记录编号 364657 评测结果 AAAAAAAAAA
题目名称 [TYVJ1730]二逼平衡树 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 1.805 s
提交时间 2017-01-17 16:25:18 内存使用 21.31 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=65610;
const double alpha=0.7;
struct node{
	int data,size;
	node *ch[2];
	node(int d=0):data(d),size(1){}
	inline void refresh(){size=ch[0]->size+ch[1]->size+1;}
	inline int cmp(int x){return x==data?-1:x>data;}
}nodes[maxn<<4],*pool[maxn<<4],*null=nodes,*root[maxn<<1],*b[maxn];
void modify(int,int,int);
int query(int,int,int);
int qpred(int,int,int);
int qsucc(int,int,int);
void copy(node*&,node*);
void merge(int,node*);
void insert(int,int);
node *&insert(int,node*&);
void erase(int,node*&);
int order(int,node*);
int pred(int,node*);
int succ(int,node*);
int erase_min(node*&);
void travel(node*);
void rebuild(int,int,node*&);
int cnt,top=1;
int n,M=1,m,a[maxn],d,l,r,x;
int main(){
	freopen("psh.in","r",stdin);
	freopen("psh.out","w",stdout);
	null->size=0;
	null->ch[0]=null->ch[1]=null;
	for(int i=0;i<maxn<<4;i++)pool[i]=&nodes[i];
	scanf("%d%d",&n,&m);
	while(M<n+2)M<<=1;
	fill(root+1,root+(M<<1),null);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		*(root[i+M]=pool[top++])=node(a[i]);
		root[i+M]->ch[0]=root[i+M]->ch[1]=null;
	}
	for(int i=M-1;i;i--){
		copy(root[i],root[i<<1]);
		merge(i,root[i<<1|1]);
	}
	while(m--){
		scanf("%d",&d);
		if(d==1){
			scanf("%d%d%d",&l,&r,&x);
			printf("%d\n",query(l,r,x)+1);
		}
		else if(d==2){
			scanf("%d%d%d",&l,&r,&x);
			int L=0,R=1e8,M;
			while(L<=R){
				M=(L+R)>>1;
				if(query(l,r,M)>=x)R=M-1;
				else L=M+1;
			}
			printf("%d\n",R);
		}
		else if(d==3){
			scanf("%d%d",&x,&d);
			modify(x,a[x],d);
			a[x]=d;
		}
		else if(d==4){
			scanf("%d%d%d",&l,&r,&x);
			printf("%d\n",qpred(l,r,x));
		}
		else{
			scanf("%d%d%d",&l,&r,&x);
			printf("%d\n",qsucc(l,r,x));
		}
	}
	return 0;
}
void modify(int x,int u,int v){
	for(x+=M;x;x>>=1){
		erase(u,root[x]);
		insert(v,x);
	}
}
int query(int l,int r,int d){
	int ans=0;
	for(l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){
		if(~l&1)ans+=order(d,root[l^1]);
		if(r&1)ans+=order(d,root[r^1]);
	}
	return ans;
}
int qpred(int l,int r,int d){
	int ans=1<<31;
	for(l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){
		if(~l&1)ans=max(ans,pred(d,root[l^1]));
		if(r&1)ans=max(ans,pred(d,root[r^1]));
	}
	return ans;
}
int qsucc(int l,int r,int d){
	int ans=(~0u)>>1;
	for(l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){
		if(~l&1)ans=min(ans,succ(d,root[l^1]));
		if(r&1)ans=min(ans,succ(d,root[r^1]));
	}
	return ans;
}
void copy(node *&x,node *y){
	if(y==null){
		x=null;
		return;
	}
	*(x=pool[top++])=node(y->data);
	copy(x->ch[0],y->ch[0]);
	copy(x->ch[1],y->ch[1]);
	x->refresh();
}
void merge(int x,node *y){
	if(y==null)return;
	insert(y->data,x);
	merge(x,y->ch[0]);
	merge(x,y->ch[1]);
}
void insert(int x,int rt){
	node *&y=insert(x,root[rt]);
	if(y!=null){
		cnt=0;
		travel(y);
		rebuild(1,cnt,y);
	}
}
node *&insert(int x,node *&rt){
	if(rt==null){
		*(rt=pool[top++])=node(x);
		rt->ch[0]=rt->ch[1]=null;
		return null;
	}
	int d=rt->cmp(x)==1;
	node *&y=insert(x,rt->ch[d]);
	rt->refresh();
	return (max(rt->ch[0]->size,rt->ch[1]->size)>rt->size*alpha)?rt:y;
}
void erase(int x,node *&rt){
	int d=rt->cmp(x);
	if(d==-1){
		if(rt->ch[0]!=null&&rt->ch[1]!=null)rt->data=erase_min(rt->ch[1]);
		else{
			pool[--top]=rt;
			rt=rt->ch[0]!=null?rt->ch[0]:rt->ch[1];
		}
	}
	else erase(x,rt->ch[d]);
	if(rt!=null)rt->refresh();
}
int order(int x,node *rt){
	int ans=0,d;
	while(rt!=null){
		if((d=x>rt->data))ans+=rt->ch[0]->size+1;
		rt=rt->ch[d];
	}
	return ans;
}
int pred(int x,node *rt){
	int ans=1<<31,d;
	while(rt!=null){
		if((d=x>rt->data))ans=rt->data;
		rt=rt->ch[d];
	}
	return ans;
}
int succ(int x,node *rt){
	int ans=(~0u)>>1,d;
	while(rt!=null){
		if((d=x<rt->data))ans=rt->data;
		rt=rt->ch[d^1];
	}
	return ans;
}
int erase_min(node *&x){
	if(x->ch[0]==null){
		pool[--top]=x;
		int tmp=x->data;
		x=x->ch[1];
		return tmp;
	}
	else{
		int tmp=erase_min(x->ch[0]);
		x->refresh();
		return tmp;
	}
}
void travel(node *x){
	if(x==null)return;
	travel(x->ch[0]);
	b[++cnt]=x;
	travel(x->ch[1]);
}
void rebuild(int l,int r,node *&x){
	if(l>r){
		x=null;
		return;
	}
	int mid=(l+r)>>1;
	x=b[mid];
	rebuild(l,mid-1,x->ch[0]);
	rebuild(mid+1,r,x->ch[1]);
	x->refresh();
}