记录编号 310694 评测结果 AAAAAAAAAA
题目名称 [TYVJ1730]二逼平衡树 最终得分 100
用户昵称 Gravatar天一阁 是否通过 通过
代码语言 C++ 运行时间 3.478 s
提交时间 2016-09-22 21:42:51 内存使用 6.04 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>

#define N 50010
#define INF 0x3f3f3f3f
#define elif else if
#define l(x) ch[x][0]
#define r(x) ch[x][1]

using namespace std;

struct node{
	node *ch[2];
	int sum,r,cnt,v;
	node* init(int x);
	void update(){
		sum=cnt;
		if(ch[0]!=NULL) sum+=ch[0]->sum;
		if(ch[1]!=NULL) sum+=ch[1]->sum;
	}
}Null;

int a[N],n,m,totn,ch[N<<1][2];
bool flag;

inline void qread(int &x){
	char ch;
	int k=1;
	while(!isdigit(ch=getchar()))
		if(ch=='-') k=-1;
	x=ch-'0';
	while(isdigit(ch=getchar()))
		x=(x<<1)+(x<<3)+ch-'0';
	x*=k;
}

node *root[N*25];

node* node::init(int x){
	v=x;
	r=rand();
	sum=1;
	cnt=1;
	ch[0]=ch[1]=&Null;
	return this;
}

void rot(node* &o,int x){
	node* tmp=o->ch[x];
	o->ch[x]=tmp->ch[x^1];
	tmp->ch[x^1]=o;
	o->update(); o=tmp;
	o->update();
}

void insert(node* &o,int x){
	if(o==&Null){
		o=new node();
		o=o->init(x);
	}
	else if(o->v==x) o->cnt++,o->sum++;
	else{
  		int d= x<=o->v? 0:1;
		insert(o->ch[d],x);
		o->update();
		if(o->ch[d]->r > o->r) rot(o,d);
	}
}

int qrank(node* &o,int x){
	if(o==&Null) return 0;
	if(o->v==x){
		flag=true;
		return o->ch[0]->sum;
	}
	if(x<o->v) return qrank(o->ch[0],x);
	return o->ch[0]->sum+qrank(o->ch[1],x)+o->cnt;
}

void del(node* &o,int x){
	if(o->v==x){
		if(o->cnt>1) o->cnt--,o->sum--;
		else{
			if(o->ch[0]==&Null && o->ch[1]==&Null) o=&Null;
			elif(o->ch[0]==&Null) o=o->ch[1];
			elif(o->ch[1]==&Null) o=o->ch[0];
			else{
				int d2 = (o->ch[0]->r >
					o->ch[1]->r?1:0);
				rot(o,d2^1);
				del(o->ch[d2],x);
			}
		}
	}
	else{
		if(x<=o->v) del(o->ch[0],x);
		else del(o->ch[1],x);
	}
	if(o!=&Null) o->update();
}

int qpre(node* &o,int x){	//x的前驱 
	if(o==&Null) return 0;
	if(x>o->v) return max(o->v,qpre(o->ch[1],x));
	return qpre(o->ch[0],x);
}

int qsuc(node* &o,int x){	//x的后继 
	if(o==&Null) return INF;
	if(x<o->v) return min(o->v,qsuc(o->ch[0],x));
	return qsuc(o->ch[1],x);
}

int build(int l,int r){
	int x=++totn;
	root[x]=&Null;
    for(int i=l;i<=r;i++){
		insert(root[x],a[i]);
	}
	if(l==r) return x;
	int mid=(l+r)>>1;
	l(x)=build(l,mid);
	r(x)=build(mid+1,r);
	return x;
}

int askk(int x,int l,int r,int ql,int qr,int qv){
	if(ql<=l && r<=qr) return qrank(root[x],qv);
	int mid=(l+r)>>1,ans=0;
	if(ql<=mid) ans+=askk(l(x),l,mid,ql,qr,qv);
	if(mid<qr) ans+=askk(r(x),mid+1,r,ql,qr,qv);
	return ans;
}

inline int ask_rank(int l,int r,int x){
	node* tmp=root[1];
	flag=0;
	int t=askk(1,1,n,l,r,tmp->v),ans;
	while(tmp!=&Null){
		if(t+1<=x){
			if(flag) ans=tmp->v;
			tmp=tmp->ch[1];
   			if(tmp!=&Null){
				flag=0;
				t=askk(1,1,n,l,r,tmp->v);
      		}
		}
		else{
            tmp=tmp->ch[0];
			if(tmp!=&Null){
				flag=0;
				t=askk(1,1,n,l,r,tmp->v);
   			}
		}
	}
	return ans;
}

void change(int x,int l,int r,int qx,int qw){
	del(root[x],a[qx]);
	insert(root[x],qw);
	if(l==r) return;
	int mid=(l+r)>>1;
	if(qx<=mid) change(l(x),l,mid,qx,qw);
	else change(r(x),mid+1,r,qx,qw);
}

int ask_pre(int x,int l,int r,int ql,int qr,int qx){
	if(ql<=l && r<=qr) return qpre(root[x],qx);
	int mid=(l+r)>>1,ans=-INF;
	if(ql<=mid) ans=max(ans,ask_pre(l(x),l,mid,ql,qr,qx));
	if(mid<qr) ans=max(ans,ask_pre(r(x),mid+1,r,ql,qr,qx));
	return ans;
}

int ask_suc(int x,int l,int r,int ql,int qr,int qx){
	if(ql<=l && r<=qr) return qsuc(root[x],qx);
	int mid=(l+r)>>1,ans=INF;
	if(ql<=mid) ans=min(ans,ask_suc(l(x),l,mid,ql,qr,qx));
	if(mid<qr) ans=min(ans,ask_suc(r(x),mid+1,r,ql,qr,qx));
	return ans;
}

int main(){
	freopen("psh.in","r",stdin);
	freopen("psh.out","w",stdout);
	srand(time(NULL));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) qread(a[i]);
	build(1,n);
	for(int i=1,cmd,x,y,z;i<=m;i++){
		qread(cmd);
		if(cmd==1){
			qread(x);
			qread(y);
			qread(z);
			printf("%d\n",askk(1,1,n,x,y,z)+1);
		}
		elif(cmd==2){
            qread(x);
			qread(y);
			qread(z);
            printf("%d\n",ask_rank(x,y,z));
		}
		elif(cmd==3){
			qread(x);
			qread(y);
			change(1,1,n,x,y);
			a[x]=y;
		}
		elif(cmd==4){
			qread(x);
			qread(y);
			qread(z);
			printf("%d\n",ask_pre(1,1,n,x,y,z));
		}
		else{
			qread(x);
			qread(y);
			qread(z);
			printf("%d\n",ask_suc(1,1,n,x,y,z));
		}
	}
	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
*/