玄学Treap 37~44pts 求调
查看原帖
玄学Treap 37~44pts 求调
616733
Lysea楼主2023/10/7 21:11

每次提交WA和AC都不一样。。。

#include<bits/stdc++.h>
#define int long long
#define N 5000005
#define INF 1e18
using namespace std;
struct Treap{
	int l,r,v,rnd,siz,cnt;
}e[N];
int n,rt,tot;
int dot(int v){
	e[++tot]={0,0,v,rand(),1,1};
	return tot;
}
void push_up(int p){
	e[p].siz=e[e[p].l].siz+e[e[p].r].siz+e[p].cnt;
}
void build(){
	rt=dot(-INF),e[rt].r=dot(INF);
	push_up(rt);
}
void Lxz(int &p){
	int tmp=e[p].r;
	e[p].r=e[tmp].l,e[tmp].l=p;
	p=tmp;
	push_up(e[p].l),push_up(p);
}
void Rxz(int &p){
	int tmp=e[p].l;
	e[p].l=e[tmp].r,e[tmp].r=p;
	p=tmp;
	push_up(e[p].r),push_up(p);
}
void insert(int &p,int v){
	if(!p){
		p=dot(v);
		return;
	}
	if(v==e[p].v) e[p].cnt++;
	else{
		if(v<e[p].v){
			insert(e[p].l,v);
			if(e[p].rnd<e[e[p].l].rnd) Rxz(p);
		}
		else{
			insert(e[p].r,v);
			if(e[p].rnd<e[e[p].r].rnd) Lxz(p);
		}
	}
	push_up(p);
}
void remove(int &p,int v){
	if(!p) return;
	if(v==e[p].v){
		if(e[p].cnt>1){
			e[p].cnt--,push_up(p);
			return;
		}
		if(e[p].l||e[p].r){
			if(!e[p].r||e[e[p].l].rnd<e[e[p].r].rnd) Rxz(p),remove(e[p].r,v);
			else Lxz(p),remove(e[p].l,v);
		}else p=0;
		return;
	}
	if(v<e[p].v) remove(e[p].l,v);
	else remove(e[p].r,v);
}
int rnk(int p,int v){
	if(!p) return 1;
	if(v==e[p].v) return e[e[p].l].siz+1;
	if(v<e[p].v) return rnk(e[p].l,v);
	return e[e[p].l].siz+e[p].cnt+rnk(e[p].r,v);
}
int value(int p,int rk){
	if(!p) return INF;
	if(rk<=e[e[p].l].siz) return value(e[p].l,rk);
	if(rk<=e[e[p].l].siz+e[p].cnt) return e[p].v;
	return value(e[p].r,rk-e[e[p].l].siz-e[p].cnt);
}
int pre(int p,int v){
	int res;
	while(p){
		if(e[p].v<v) res=e[p].v,p=e[p].r;
		else p=e[p].l;
	}
	return res;
}
int nxt(int p,int v){
	int res;
	while(p){
		if(e[p].v>v) res=e[p].v,p=e[p].l;
		else p=e[p].r;
	}
	return res;
}
signed main(){
	ios::sync_with_stdio(false);
	srand(time(NULL));
	build(),cin>>n;
	int op,x;
	while(n--){
		cin>>op>>x;
		if(op==1) insert(rt,x);
		if(op==2) remove(rt,x);
		if(op==3) cout<<rnk(rt,x)-1<<endl;
		if(op==4) cout<<value(rt,x+1)<<endl;
		if(op==5) cout<<pre(rt,x)<<endl; 
		if(op==6) cout<<nxt(rt,x)<<endl;
	} 
    return 0;
}
2023/10/7 21:11
加载中...