51pts 求调 悬3关
查看原帖
51pts 求调 悬3关
782210
Yu_Chengxuan楼主2024/9/5 17:05
#include <bits/stdc++.h>
#define int long long
#define inf 1e9
using namespace std;

inline int read() {
	int x=0,f=1;
	char ch=getchar();
	while (ch<'0'||ch>'9') {
		if (ch=='-') f=-1;
		ch=getchar();
	}
	while (ch>='0'&& ch<='9') {
		x=x*10+ch-48;
		ch=getchar();
	}
	return x*f;
}
const int maxn = 1e5 + 10;
struct node{
	int lc,rc,pri,cnt,val,siz;
	#define lc(x) treap[x].lc
	#define rc(x) treap[x].rc
	#define p(x) treap[x].pri
	#define c(x) treap[x].cnt
	#define val(x) treap[x].val
	#define siz(x) treap[x].siz
}treap[maxn];
int tot,root; 
inline void update(int &x){
	siz(x) = siz(lc(x)) + siz(rc(x)) + c(x);
}
int newnode(int x){
	treap[++tot].val = x;
	p(tot) = rand();
	c(tot) = 1;
	siz(tot) = 1;
	return tot;
}
void build(){
	root=newnode(-inf);
	rc(root)=newnode(inf);
	update(root);
}
inline void zig(int &x){
	int k=lc(x);
	lc(x)=rc(k);
	rc(k)=x;
	siz(k)=siz(x);
	update(x);
	x=k;
}
inline void zag(int &x){
	int k=rc(x);
	rc(x)=lc(k);
	lc(k)=x;
	siz(k)=siz(x);
	update(x);
	x=k;
}
void insert(int &x,int v){
    if(!x){
		x=newnode(v);
    	return ;
    }	
    else ++siz(x);
    if (val(x)==v){
    	++c(x);
	}
    if(v<val(x)){
        insert(lc(x),v);
        if (p(lc(x))<p(x)){
        	zig(x);
		}
	}
    else{
        insert(rc(x),v);
        if (p(rc(x))<p(x)){
        	zag(x);
		}
	}	
}
void remove(int &x,int v){
	if (v==val(x)){
		if (c(x)>1){
			c(x)--;
			siz(x)--;
		}
		else if (!lc(x) || !rc(x)){
			x=lc(x)+rc(x);
		}
		else if (p(lc(x))<p(rc(x))){
			zig(x);
			remove(x,v);
		}
		else{
			zag(x);
			remove(x,v);				
		}
		return ;
	}
	siz(x)--;
    if(v<val(x))
        remove(lc(x),v);
    else
        remove(rc(x),v);
    return ;
}

inline int pre(int v){
	int x=root,res=-inf;
	while (x){
		if (val(x)<=v){
			res=val(x);
			x=rc(x);
		}
		else{
			x=lc(x);
		}
	}
	return res;
}
inline int suf(int v){
	int x=root,res;
	while (x){
		if (val(x)>v){
			res=val(x);	
			x=lc(x);
		}
		else{
			x=rc(x);
		}
	}
	return res;	
}
inline int kth(int k){
	int x=root;
	while (x){
		if (siz(lc(x))<k && siz(lc(x))+c(x)>=k){
			return val(x);
		}
		if (siz(lc(x))>=k) x=lc(x);
		else k-=siz(lc(x))+c(x),x=rc(x);
	}
	return 0;
}
inline int getrank(int k){
	int x=root,res=0;
	while (x){
		if (k==val(x)) return res+siz(lc(x))+1;
		if (k<val(x)) x=lc(x);
		else res+=siz(lc(x))+c(x),x=rc(x);
	}
	return res;
}
signed main(){	
	freopen("P3369_1.in","r",stdin);
	build();
	int n=read();
	while (n--){
		int opr = read(),x = read();
		if(opr == 1) insert(root,x);
		else if(opr == 2) remove(root,x);
		else if(opr == 3){
			cout << getrank(x)-1 << '\n';
		}
		else if(opr == 4){
			cout << kth(x+1) << '\n';
		}
		else if(opr == 5){
			cout << pre(x) << '\n';
		}
		else if(opr==6){
			cout << suf(x) << '\n';
		}
	}
}
2024/9/5 17:05
加载中...