小压treap求调
查看原帖
小压treap求调
464001
5793__qwq楼主2023/7/2 21:55
#include<bits/stdc++.h>
#define l son[x][0]
#define r son[x][1]
using namespace std;
int n,f,x,y,sum,son[100001][2],v[100001],rep[100001],size[100001],rnk[100001];
void push(int x){size[x]=size[l]+size[r]+rep[x];}
void rot(int &x,int f){
	int k=son[x][1-f];
    son[x][1-f]=son[k][f];
    son[k][f]=x;
    push(x);
    push(k);
    x=k;
}
void ins(int &x,int val){
	if(!x){x=++sum;v[x]=val,size[x]=rep[x]=1,rnk[x]=rand();return;}
	if(v[x]==val){++size[x],++rep[x];return;}
	int f=0;
	if(val>v[x])ins(r,val),f=1;
	else ins(l,val);
	if(rnk[x]<rnk[r])rot(x,f);
	push(x);
}
void del(int &x,int val){
	if(!x)return;
	if(val>v[x])del(r,val);
	else del(l,val);
	if(!l&&!r){
		--size[x],--rep[x];
		if(!size[x])x=0;
	}
	else if(l&&!r){rot(x,1);del(r,val);}
	else if(!l&&r){rot(x,0);del(l,val);}
	else {
		if(v[l]<v[r]){rot(x,1);del(r,val);}
		else{rot(x,0);del(l,val);}
	}
}
int rak(int x,int val){
	if(!x)return -1;
	if(v[x]==val)return size[l]+1;
	if(val>v[x])return size[l]+1+rak(r,val);
	return rak(l,val);
}
int find(int x,int val){
	if(!x)return -1;
	if(size[l]>=val)return find(l,val);
	if(size[l]+rep[x]<val)return find(r,val-size[l]-rep[x]);
	return v[x];
}
int pre(int x,int val){
	if (!x) return -1;
	if (v[x]>=val) return pre(l,val);
    return max(v[x],pre(r,val));
}
int nxt(int x,int val){
	if (!x) return -1;
	if (v[x]<=val) return nxt(r,val);
    return min(v[x],nxt(l,val));
}
int main(){
	cin>>n;
	while(n--){
		cin>>f>>y;
		if(f==1)ins(x,y);
		else if(f==2)del(x,y);
		else if(f==3)cout<<rak(x,y)<<'\n';
		else if(f==4)cout<<find(x,y)<<'\n';
		else if(f==5)cout<<pre(x,y)<<'\n';
		else if(f==6)cout<<nxt(x,y)<<'\n';
	}
	return 0;
}

2023/7/2 21:55
加载中...