萌新求教
查看原帖
萌新求教
183609
hhoppitreeMadeline楼主2020/5/10 19:28
#include<bits/stdc++.h>
#define INF 0x7fffffff
#define MAXN 100005
using namespace std;
inline int read(){
    int res=0;
    char c;
    bool zf=0;
    while(((c=getchar())<'0'||c>'9')&&c!= '-');
    if(c=='-')zf=1;
    else res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=(res<<3)+(res<<1)+c-'0';
    if(zf)return -res;
    return res;
}
struct Treap{
	int lc,rc,num,prio,cnt,sze;
}dot[MAXN];
int r,root;
unsigned long long nowrandom=INT_MAX-1;
inline int Random(){
	nowrandom=((nowrandom<<10)+(nowrandom<<1)+(nowrandom>>1)+nowrandom*123456789)%INT_MAX;
	nowrandom=nowrandom*987654321%INT_MAX;
	return nowrandom;
}
inline void uptsze(int x){
	dot[x].sze=dot[dot[x].lc].sze+dot[dot[x].rc].sze+dot[x].cnt;
	return;
}
inline void Zig(int &x){
	int t=dot[x].lc;
	dot[x].lc=dot[t].rc;
	dot[t].rc=x;
	dot[t].sze=dot[x].sze;
	uptsze(x);
	x=t;
	return;
}
inline void Zag(int &x){
	int t=dot[x].rc;
	dot[x].rc=dot[t].lc;
	dot[t].lc=x;
	dot[t].sze=dot[x].sze;
	uptsze(x);
	x=t;
	return;
}
inline void newnode(int &x,int num){
	x=(++r);
	dot[x].num=num;
	dot[x].prio=Random();
	dot[x].cnt=1;
	dot[x].sze=1;
	dot[x].lc=dot[x].rc=0;
	return;
}
void insert(int &x,int num){
	if(!x){
		newnode(x,num);
		return;
	}
	dot[x].sze++;
	if(dot[x].num==num){
		dot[x].cnt++;
		return;
	}
	if(num<dot[x].num){
		insert(dot[x].lc,num);
		if(dot[dot[x].lc].prio<dot[x].prio)Zig(x);
	}
	else{
		insert(dot[x].rc,num);
		if(dot[dot[x].rc].prio<dot[x].prio)Zag(x);
	}
	return;
} 
void Delete(int &x,int num){
	dot[x].sze--;
	if(dot[x].num==num){
		if(dot[x].cnt>1){
			dot[x].cnt--;
			return;
		}
		if(!dot[x].lc||!dot[x].rc){
			x=dot[x].lc?dot[x].lc:dot[x].rc;
			return;
		}
		dot[dot[x].lc].num<dot[dot[x].rc].num?Zig(x):Zag(x);
		Delete(x,num);
		return;
	}
	if(num<dot[x].num)Delete(dot[x].lc,num);
	else Delete(dot[x].rc,num);
	return;
}
inline int askpre(int data){
	int now=root,ans=-INF;
	while(now){
		if(dot[now].num<data)ans=dot[now].num,now=dot[now].rc;
		else now=dot[now].lc;
	}
	return ans;
}
inline int asknex(int data){
	int now=root,ans=INF;
	while(now){
		if(dot[now].num>data)ans=dot[now].num,now=dot[now].lc;
		else now=dot[now].rc;
	}
	return ans;
}
inline int askkth(int k){
	int now=root;
	while(now){
		if(dot[dot[now].lc].sze<k&&dot[dot[now].lc].sze+dot[now].cnt>=k)return dot[now].num;
		if(dot[dot[now].lc].sze>=k)now=dot[now].lc;
		else k-=dot[dot[now].lc].sze+dot[now].cnt,now=dot[now].rc;
	}
	return 0;
}
inline int askrank(int data){
	int now=root,ans=0;
	while(now){
		if(data==dot[now].num)return ans+dot[dot[now].lc].sze+1;
		if(data<dot[now].num)now=dot[now].lc;
		else ans+=dot[dot[now].lc].sze+dot[now].cnt,now=dot[now].rc;
	}
	return ans;
}
signed main(){
	int n=read();
	while(n--){
		int opt=read(),x=read();
		switch(opt){
			case 1:{
				insert(root,x);
				break;
			}
			case 2:{
				Delete(root,x);
				break;
			}
			case 3:{
				cout<<askrank(x)<<'\n';
				break;
			}
			case 4:{
				cout<<askkth(x)<<'\n';
				break;
			}
			case 5:{
				cout<<askpre(x)<<'\n';
				break;
			}
			case 6:{
				cout<<asknex(x)<<'\n';
				break;
			}
		}
	}
	return 0;
}

52pts

2020/5/10 19:28
加载中...