爆〇求助
查看原帖
爆〇求助
138960
Tenshi楼主2021/5/26 17:27

将之前AC的普通平衡树代码贴过来改一下操作,结果全部wa了,不知道哪里有问题(应该是有坑点?),求助聚聚。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int INF=2147483647;
inline int read(){
   int s=0,w=1;
   char ch=getchar();	
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}

const int N=2e5+5;
struct node{
	int s[2],p,v;
	int size,cnt;
	void init(int _p,int _v){
		p=_p, v=_v;
		size=cnt=1;
	}
}tr[N];
int idx,root;

void pushup(int u){
	tr[u].size=tr[tr[u].s[0]].size+tr[tr[u].s[1]].size+tr[u].cnt;
}

void rotate(int x){
	int y=tr[x].p, z=tr[y].p;
	int k=tr[y].s[1]==x;
	tr[z].s[tr[z].s[1]==y]=x, tr[x].p=z;
	tr[tr[x].s[k^1]].p=y, tr[y].s[k]=tr[x].s[k^1];
	tr[y].p=x, tr[x].s[k^1]=y;
	pushup(y), pushup(x);
}

void splay(int x,int k){
	while(tr[x].p!=k){
		int y=tr[x].p, z=tr[y].p;
		if(z!=k)
			if((tr[z].s[1]==y) ^ (tr[y].s[1]==x)) rotate(x);
			else rotate(y);
		rotate(x);
	}
	if(k==0) root=x;
}

void insert(int v){
	int u=root, p=0;
	while(u && tr[u].v!=v) p=u, u=tr[u].s[v>tr[u].v];
	if(u) tr[u].cnt++, tr[u].size++;
	else{
		u=++idx;
		if(p) tr[p].s[v>tr[p].v]=u;
		tr[u].init(p,v); // update the msg of the new node
	}
	splay(u,0);
}

void find(int v){
	int u=root;
	if(!u) return;
	while(v!=tr[u].v && tr[u].s[v>tr[u].v]) u=tr[u].s[v>tr[u].v];
	splay(u,0);
}

int pre(int v){
	find(v);
	int u=root;
	if(tr[u].v<v) return u; // 如果树中所有数的值都没有 v 大,那么 v 的前驱一定是 u 
	u=tr[u].s[0];
	while(tr[u].s[1]) u=tr[u].s[1];
	return u;
}

int suf(int v){
	find(v);
	int u=root;
	if(tr[u].v>v) return u; // 如果树中所有数的值都没有 v 小,那么 v 的后继一定是 u 
	u=tr[u].s[1];
	while(tr[u].s[0]) u=tr[u].s[0];
	return u;
}

void remove(int v){
	int pu=pre(v), su=suf(v);
	splay(pu,0);splay(su,pu);
	int u=tr[su].s[0]; // the point to remove;
	if(tr[u].cnt>1) tr[u].cnt--, splay(u,0);
	else tr[su].s[0]=0;
}

int rk_for_num(int k){
	int u=root;
	while(true){
		int ls=tr[u].s[0];
		if(tr[ls].size+tr[u].cnt<k) k-=tr[ls].size+tr[u].cnt,u=tr[u].s[1];
		else if(tr[ls].size>=k) u=tr[u].s[0];
		else return tr[u].v;
	}
}

int num_for_rk(int v){
	find(v);
	return tr[tr[root].s[0]].size+1-1;
}

int main(){
	int m; cin>>m;
	insert(-INF), insert(INF);
	while(m--){
		int op, x; op=read(), x=read();
		if(op==1) cout<<num_for_rk(x)<<endl;
		else if(op==2) cout<<rk_for_num(x+1)<<endl;
		else if(op==3) cout<<tr[pre(x)].v<<endl;
		else if(op==4) cout<<tr[suf(x)].v<<endl;
		else if(op==5) insert(x);
	}
	return 0;
}
2021/5/26 17:27
加载中...