下数据自己测没问题,WA#4到#13,求调感谢
查看原帖
下数据自己测没问题,WA#4到#13,求调感谢
529841
ybxybx楼主2024/1/9 13:06
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
const int N=1e5+5;
struct node{
	int va,w;     //原值和随机值 
	int s1,s2;    //出现次数和子树个数
	int l,r;      //左子树和右子树 
}tr[N<<2];
int n,cnt,root,ans1;
int newnode(int x){
	tr[++cnt].va=x;
	tr[cnt].w=rand();
	tr[cnt].s1=tr[cnt].s2=1;
	tr[cnt].l=tr[cnt].r=0; 
	return cnt;
}
void update(int rt){
	tr[rt].s2=tr[tr[rt].l].s2+tr[tr[rt].r].s2+tr[rt].s1;
	return ;
}
void split(int rt,int x,int &r1,int &r2){   //切割 
	if(rt==0){
		r1=r2=0;
		return ;
	}
	if(tr[rt].va>=x){         //判断取值,>=则继续切割左子树 
		int rr2;
		split(tr[rt].l,x,r1,rr2);
		tr[rt].l=rr2;
		r2 = rt;
	} else{                   // <则继续切割右子树 
		int rr1;
		split(tr[rt].r,x,rr1,r2);
		tr[rt].r=rr1;
		r1 = rt;
	}
	update(rt);
	return ;
}
void merge(int r1,int r2,int &rt){
	if(r1==0||r2==0){      //一方为0则另一方为根 
		rt=r1+r2;
		return ;
	}
	int rr;
	if(tr[r1].w<tr[r2].w){      //通过随机数判断谁当根 
		merge(tr[r1].r,r2,rr);
		tr[r1].r=rr;
		rt = r1;
	} else{
		merge(r1,tr[r2].l,rr);
		tr[r2].l=rr;
		rt = r2;
	}
	update(rt);
	return ;
}
void delete1(int rt,int x){
	if(rt==0) return ;
	if(tr[rt].va==x){
		if(tr[rt].s1>1) tr[rt].s1--;
		else{
			int r1,r2,r3,r4;
			split(root,x+1,r1,r2);
			merge(tr[rt].l,tr[rt].r,r3);
			merge(r3,r2,r4);
		}
		return ;
	} else if(tr[rt].va<x) delete1(tr[rt].r,x);
	else delete1(tr[rt].l,x);
	return ;
}
void fn(int rt,int x){
	if(rt==0) return ;
	if(tr[rt].va<x){
		ans1+=tr[rt].s1+tr[tr[rt].l].s2;
		fn(tr[rt].r,x);
	} else fn(tr[rt].l,x);
	return ;
}
void fn2(int rt,int x){
	if(rt==0) return ;
	if(tr[tr[rt].l].s2>=x){
		fn2(tr[rt].l,x);
		return ;
	} else{
		x -= tr[tr[rt].l].s2;
		if(x<=tr[rt].s1){
			ans1=tr[rt].va;
			return ;
		} else{
			x -= tr[rt].s1;
			fn2(tr[rt].r,x);
			return ;
		}
	}
	return ;
}
void fn3(int rt,int x){
	if(rt==0) return ;
	if(tr[rt].va<x){
		ans1=tr[rt].va;
		fn3(tr[rt].r,x);
	} else fn3(tr[rt].l,x);
	return ;
}
void fn4(int rt,int x){
	if(rt==0) return ;
	if(tr[rt].va>x){
		ans1=tr[rt].va;
		fn4(tr[rt].l,x);
	} else fn4(tr[rt].r,x);
	return ;
}
int main(){
//	freopen("P3369_4.in","r",stdin);
//	freopen("me.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	root = 0;
	cnt = 0;
	for(int i=1;i<=n;i++){
		int op,x;
		cin>>op>>x;
		ans1 = 0;
		if(op==1){     //插入一个数 
			int r1,rr2,r2,r3;
			split(root,x,r1,rr2);   //以x为节点切割 
			split(rr2,x+1,r2,r3);   //以x+1为节点切割,来判断之前是否存在x
			if(r2==0){             //之前存在x 
				r2=newnode(x);
			} else{
				tr[r2].s1++;
				tr[r2].s2++;	
			}
			merge(r1,r2,rr2);
			merge(rr2,r3,root);
		} else if(op==2) delete1(root,x); //删除一个数 
		else if(op==3){
			fn(root,x);
			cout<<ans1+1<<"\n";
		} else if(op==4){
			fn2(root,x);
			cout<<ans1<<"\n";
		} else if(op==5){
			fn3(root,x);
			cout<<ans1<<"\n";
		} else{
			fn4(root,x);
			cout<<ans1<<"\n";
		}
	}
	return 0;
}
2024/1/9 13:06
加载中...