求助平衡树
查看原帖
求助平衡树
306982
二gou子楼主2021/11/13 18:35

RT ,蒟蒻 Splay 不知道哪里出锅了只有 60 ,把 AC 了板子题的函数粘过来也过不了题,有没有巨佬帮忙看看(虽然我知道可能没有人喜欢 De 数据结构的 Bug)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e6+5,INF=2e9;
int n,q;
int a[N],ans[N];
struct ASK{
	int l,r,k,id;
}ask[N];
bool cmp(ASK A,ASK B){
	if(A.l==B.l) return A.r<B.r;
	else return A.l<B.l;
}
int root,tot,val[N],cnt[N],son[N][2],fa[N],siz[N];
int get(int x){
	return x==son[fa[x]][1];
}
void Upd(int x){
	if(x) siz[x]=cnt[x]+siz[son[x][0]]+siz[son[x][1]]; 
}
void connect(int x,int y,int z){
	fa[x]=y;
	son[y][z]=x;
}
void rotate(int x){
	int fa1=fa[x],fa2=fa[fa[x]],z1=get(x),z2=get(fa[x]);
	connect(son[x][z1^1],fa1,z1);
	connect(fa1,x,z1^1);
	connect(x,fa2,z2);
	Upd(fa1),Upd(x);
}
void Splay(int x,int goal){
	for(;goal!=fa[x];rotate(x)){
		if(goal!=fa[fa[x]]) rotate(get(x)==get(fa[x])?fa[x]:x);
	}
	if(!goal) root=x;
}
void Insert(int x){
	if(!root){
		root=++tot;
		siz[root]=cnt[root]=1;
		son[root][0]=son[root][1]=0;
		val[root]=x;
		return;
	}
	int rt=root;
	while(rt){
		if(x==val[rt]){
			cnt[rt]++;
			Splay(rt,0);
			return;
		}
		if(x<val[rt]){
			if(son[rt][0]) rt=son[rt][0];
			else{
				tot++;
				val[tot]=x;
				cnt[tot]=siz[tot]=1;
				connect(tot,rt,0);
				Splay(tot,0);
				return;
			}
		}
		else{
			if(son[rt][1]) rt=son[rt][1];
			else{
				tot++;
				val[tot]=x;
				cnt[tot]=siz[tot]=1;
				connect(tot,rt,1);
				Splay(tot,0);
				return;
			}
		}
	}
}
int GetPre(){
    int rt=son[root][0];
    while(son[rt][1]) rt=son[rt][1];
    return rt;
}
int GetRankByVal(int x){
	int rt=root,ans=0;
	while(rt){
		if(x<val[rt]){
			rt=son[rt][0];
			continue;
		}
		ans+=siz[son[rt][0]];
		if(x==val[rt]){
			Splay(rt,0);
			return ans;
		}
		ans+=cnt[rt];
		rt=son[rt][1];
	}
	return ans; 
}
void Remove(int x){
	GetRankByVal(x);
	int rt=root;
	if(cnt[rt]>1){
		cnt[rt]--;
		Upd(rt);
		return;
	}
	if(!son[rt][0]&&!son[rt][1]){
		rt=0;
		return;
	}
	if(!son[rt][0]){
		int now=rt;
		rt=son[rt][1];
		fa[rt]=0;
		return;
	}
	if(!son[rt][1]){
		int now=rt;
		rt=son[rt][0];
		fa[rt]=0;
		return;
	}
	int now=rt,left=GetPre();
	Splay(left,0);
	connect(son[now][1],root,1);
	Upd(root);
}
int GetValByRank(int x){
	int rt=root;
	while(1){
		if(siz[son[rt][0]]>=x){
		    rt=son[rt][0];
			continue;
		}
		if(son[rt][0]) x-=siz[son[rt][0]];
		if(x<=cnt[rt]){
			Splay(rt,0);
			return val[rt];
		}
		x-=cnt[rt];
		rt=son[rt][1];
	}
}
int main()
{
//	freopen("P1533_7.in","r",stdin);
//	freopen("dog.out","w",stdout);
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	
	for(int i=1;i<=q;i++){
		scanf("%d%d%d",&ask[i].l,&ask[i].r,&ask[i].k);
		ask[i].id=i;
	}
	
	sort(ask+1,ask+1+q,cmp);
	
	Insert(INF);
	Insert(-INF);
	
	int L=1,R=0;
	for(int i=1;i<=q;i++){
		while(R<ask[i].r){
			R++;
			Insert(a[R]);
		}
		while(L<ask[i].l){
			Remove(a[L]);
			L++;
		}
		ans[ask[i].id]=GetValByRank(ask[i].k+1);
	}
	
	for(int i=1;i<=q;i++){
		printf("%d\n",ans[i]);
	}
	
	return 0;
}
2021/11/13 18:35
加载中...