这道题不能用Spaly做吗?
查看原帖
这道题不能用Spaly做吗?
257621
翼德天尊楼主2020/7/29 13:40

RT

用普通平衡树模板那粘过来的代码改了改也试了,五个点全T。

平衡树不应该比普通二叉搜索树快吗?

求助各位大佬。

代码如下(不用担心正确性,只是可能从那里粘过来的不符合题意?但是我检查过了,应该没有啊):

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define gen e[0].ch[1]
#define INF 2147483647
int q,n,po;
struct node{
	int ch[2],sum,rep,fa,v;
}e[MAXN];
inline int read(){
	int w=0,f=1;
	char c=getchar();
	while (c>'9'||c<'0'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0'&&c<='9'){
		w=(w<<1)+(w<<3)+(c^48);
		c=getchar();
	}
	return w*f;
}
void addpo(int x,int fa){
	e[++n].fa=fa,e[n].rep=e[n].sum=1,e[n].v=x;
}
bool rship(int x){ return e[e[x].fa].ch[1]==x; }
void con(int son,int fa,int lr){
	e[son].fa=fa,e[fa].ch[lr]=son;
}
void ch(int x){ e[x].sum=e[e[x].ch[0]].sum+e[e[x].ch[1]].sum+e[x].rep; }
void turn(int x){
	int y=e[x].fa,ygen=e[y].fa,xship=rship(x),yship=rship(y),B=e[x].ch[xship^1];
	con(B,y,xship),con(y,x,xship^1),con(x,ygen,yship);
	ch(y),ch(x);
}
void splay(int at,int to){
	to=e[to].fa;
	while (e[at].fa!=to){
		int up=e[at].fa;
		if (e[up].fa==to) turn(at);
		else if (rship(up)==rship(at)) turn(up),turn(at);
		else turn(at),turn(at);
	} 
}
void add(int x){
	++po;
	if (po==1){
		gen=n+1;
		addpo(x,0);
	}else{
		int now=gen;
		while (1){
			e[now].sum++;
			if (e[now].v==x){
				e[now].rep++;
				splay(now,gen);
				return;
			}
			bool next=e[now].v<x;
			if (!e[now].ch[next]){
				addpo(x,now);
				e[now].ch[next]=n;
				splay(n,gen);
				return;
			}
			now=e[now].ch[next];
		}
	}
}
int find(int x){
	int now=gen;
	while (1){
		if (e[now].v==x){
			splay(now,gen);
			return now;
		}
		bool next=e[now].v<x;
		if (!e[now].ch[next]) return 0;
		now=e[now].ch[next];
	}
}
void kill(int x){
	e[x].fa=e[x].ch[0]=e[x].ch[1]=e[x].rep=e[x].sum=e[x].v=0;
	if (x==n) --n;
}
void pop(int x){
	int deal=find(x);
	if (!deal) return;
	--po;
	if (e[deal].rep>1){
		--e[deal].rep,--e[deal].sum;
		return;
	}
	if (!e[deal].ch[0]){
		gen=e[deal].ch[1];
		e[gen].fa=0;
	}else{
		int l=e[deal].ch[0],r=e[deal].ch[1];
		while (e[l].ch[1]) l=e[l].ch[1];
		splay(l,e[deal].ch[0]);
		con(r,l,1);con(l,0,1);
		ch(l);
	} 
	kill(deal);
}
int arank(int x){
	int now=gen,ans=0;
	while (1){
		if (e[now].v==x){
			ans+=1+e[e[now].ch[0]].sum;
			splay(now,gen);
			return ans;
		}
		if (e[now].v>x) now=e[now].ch[0];
		else{
			ans+=e[e[now].ch[0]].sum+e[now].rep;
			now=e[now].ch[1];
		}
	}
}
int rerank(int x){
	int now=gen;
	while (1){
		int cha=e[e[now].ch[0]].sum+e[now].rep;
		if (x>e[e[now].ch[0]].sum&&x<=cha){
			splay(now,gen);
			return e[now].v;
		}
		if (x<=e[e[now].ch[0]].sum) now=e[now].ch[0];
		else x-=cha,now=e[now].ch[1];
	}
}
int low(int x){
	int now=gen,ans=-INF;
	while (now){
		if (e[now].v<x&&e[now].v>ans) ans=e[now].v,splay(now,gen);
		if (e[now].v>=x) now=e[now].ch[0];
		else now=e[now].ch[1];
	}
	return ans;
}
int upp(int x){
	int now=gen,ans=INF;
	while (now){
		if (e[now].v>x&&e[now].v<ans) ans=e[now].v,splay(now,gen);
		if (e[now].v<=x) now=e[now].ch[1];
		else now=e[now].ch[0];
	}
	return ans;
}
int main(){
	q=read();
	while (q--){
		int op=read(),x=read();
		if (op==1) printf("%d\n",arank(x));
		else if (op==2) printf("%d\n",rerank(x));
		else if (op==3) printf("%d\n",low(x));
		else if (op==4) printf("%d\n",upp(x));
		else add(x);
	} 
    return 0;
}
2020/7/29 13:40
加载中...