splay#2WA求条
查看原帖
splay#2WA求条
673342
fried_chicken楼主2024/1/26 17:03
#include<bits/stdc++.h>
using namespace std;
#define file(filename) freopen(filename".in","r",stdin),freopen(filename".out","w",stdout)
#define endl "\n"
#define first fi
#define second sc
using ll=long long;using ull=unsigned long long;using ld=long double;using pii=pair<int,int>;using pll=pair<ll,ll>;using vi=vector<int>;using sti=stack<int>;using seti=set<int>;using mii=map<int,int>;using piii=pair<int,pair<int,int> >;using pq=priority_queue<int>;using pqs=priority_queue<int,vector<int>,greater<int> >;
#define mem(a,num) memset(a,num,sizeof(a))
#define sort_(a,n) sort(a+1,a+n+1)
#define sort_cmp(a,n) sort(a+1,a+n+1,cmp)
#define keep(n) fixed<<setprecision(n)
#define LF putchar('\n')
#define SP putchar(' ')
#define debug(x) cout<<#x<<'='<<x<<endl;
#define randint(l,r) rand()%((r)-(l)+1)+(l)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define all(x) x.begin(),x.end()
#define pb push_back
#define rush(T) while(T--)
namespace fast_io{
   template <typename T>inline void read(T& x) {x = 0; char ch = getchar();ll f = 1;while (!isdigit(ch)) {if (ch == '-')f *= -1;ch = getchar();} while (isdigit(ch)) {x = x * 10 + ch - 48;ch = getchar();}x *= f;}template <typename T, typename... Args>void read(T& first, Args&... args) {read(first);read(args...);}
   template <typename T>inline void write(T arg) {T x = arg;if (x < 0) {putchar('-');x = -x;}if (x > 9) { write(x / 10);} putchar(x % 10 + '0');}template <typename T, typename... Ts>void write(T arg, Ts... args) {write(arg); if (sizeof...(args) != 0) { putchar(' ');write(args...);}}
   inline __int128 rd(){__int128 sum=0,fl=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()){if(ch=='-')fl=-1;}for(;isdigit(ch);ch=getchar()){sum=sum*10+ch-'0';}return sum*fl;}
   template <typename T>inline void readA(T x[],int len){for(int i=1;i<=len;i++){read(x[i]);}}
   inline void readS(string &s){char ch=getchar();while(ch==' '||ch=='\n') {ch=getchar();}while(ch!=' '&&ch!='\n') {s+=ch,ch=getchar();}}
   inline void readSL(string &s){char ch=getchar();while(ch=='\n') {ch=getchar();}while(ch!='\n') {s+=ch,ch=getchar();}}
   inline void readC(char s[]){int tot=0;char ch=getchar();while(ch==' '||ch=='\n') {ch=getchar();}while(ch!=' '&&ch!='\n') {s[tot++]=ch,ch=getchar();}}
   inline void writeS(string s){int len=s.length();for(int i=0;i<len;i++){putchar(s[i]);}}
   inline void readD(double &x){scanf("%lf",&x);}
   inline void writeD(double x){printf("%lf",x);}
   inline void keepD(double x,int len){printf("%.*lf",len,x);}
   inline void writeC(char s[],int len){for(int i=0;i<len;i++){putchar(s[i]);}}
   template <typename T>inline void readV(vector<T> &v,int n){for(int i=1;i<=n;i++){T x;read(x);v.push_back(x);}}
   template <typename T>inline void writeA(T x[],int len){for(int i=1;i<=len;i++){write(x[i]),SP;}}
   template <typename T>inline void writeV(vector<T> &v,int n){for(int i=1;i<=n;i++){write(v[i]),SP;}}
   inline void readc(char &x){x=getchar();}template <typename T, typename... Args>void readc(T & first, Args &... args) {readc(first);readc(args...);}
   inline void writec(char x){putchar(x);}template <typename T, typename... Ts>void writec(T arg, Ts... args) {writec(arg); if (sizeof...(args) != 0) { putchar(' ');writec(args...);}}
   inline char rdc(){return getchar();}
}using namespace fast_io;
const int N=1e5+10;
//复杂度O(logn) 
struct node{
	int s[2];//左右儿子
	int p;//父亲
	int v;//结点权值
	int cnt;//权值出现次数
	int size;//子树大小
	void init(int p1,int v1){
		p=p1,v=v1;
		cnt=size=1;
	} 
}tr[N];
int root;//节点编号
int idx;//节点个数 
void pushup(int x){	tr[x].size=tr[tr[x].s[0]].size+tr[tr[x].s[1]].size+tr[x].cnt;} 
//1.旋转(保序且信息正确) ,包括右旋和左旋 
void rotate(int x){
	int y=tr[x].p,z=tr[y].p;
	int k=tr[y].s[1]==x;
	tr[y].s[k]=tr[x].s[k^1];
	tr[tr[x].s[k^1]].p=y;
	tr[x].s[k^1]=y;
	tr[y].p=x;
	tr[z].s[tr[z].s[1]==y]=x;
	tr[x].p=z;
	pushup(y),pushup(x);
}
//2.伸展(访问一个节点x,并把x旋转到根节点) k>0时,把x转到k下面,k=0时把x转到根 
void splay(int x,int k){
	while(tr[x].p!=k){
		int y=tr[x].p,z=tr[y].p;
		if(z!=k)(tr[y].s[0]==x)^(tr[z].s[0]==y)?rotate(x):rotate(y);//折转底,直转中
		rotate(x); 
	}if(k==0) root=x;
}
//3.查找(找到v所在节点,并把该节点旋转到根) 
void find(int v){//找到v并转到根 
	int x=root;
	while(tr[x].s[v>tr[x].v]&&v!=tr[x].v) x=tr[x].s[v>tr[x].v];
	splay(x,0);
}
//4.前驱(求v的前驱,返回其节点编号) 
int get_pre(int v){
	find(v);
	int x=root;
	if(tr[x].v<v) return x;
	x=tr[x].s[0];
	while(tr[x].s[1])x=tr[x].s[1];
	return x;
}
//5.后继 (求v的后继,返回其节点编号) 
int get_suc(int v){
	find(v);
	int x=root;
	if(tr[x].v>v) return x;
	x=tr[x].s[1];
	while(tr[x].s[0])x=tr[x].s[0];
	return x;
}
//6.删除(删除v,若有多个相同的数,只删除一个) 
void del(int v){
	int pre=get_pre(v);
	int suc=get_suc(v);
	splay(pre,0),splay(suc,pre);
	int del=tr[suc].s[0];
	if(tr[del].cnt>1) tr[del].cnt--,splay(del,0);
	else tr[suc].s[0]=0,splay(suc,0);
}
//7.排名(查询v数的排名) 
int get_rank(int v){
	find(v);
	return tr[tr[root].s[0]].size;
}
//8.数值(查询排名为k的数值) 
int get_val(int k){
	int x=root;
	while(1){
		int y=tr[x].s[0];
		if(tr[y].size+tr[x].cnt<k){
			k-=tr[y].size+tr[x].cnt;
			x=tr[x].s[1];
		}else{
			if(tr[y].size>=k) x=tr[x].s[0];
			else break;
		}
	}splay(x,0);
	return tr[x].v;
}
//9.插入(插入v) 
void insert(int v){
	int x=root,p=0;
	while(x&&tr[x].v!=v) p=x,x=tr[x].s[v>tr[x].v];
	if(x) tr[x].cnt++;
	else{
		x=++idx;
		tr[p].s[v>tr[p].v]=x;
		tr[x].init(p,v);
	}splay(x,0);
}
int main() {
    //file("");
    //ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	insert(-1e8),insert(1e8);
	int n=rd();
	rush(n){
		int op=rd(),x=rd();
		switch(op){
			case 1:insert(x);break;
			case 2:del(x);break;
			case 3:write(get_rank(x)),LF;break;
			case 4:write(get_val(x+1)),LF;break;
			case 5:write(tr[get_pre(x)].v),LF;break;
			case 6:write(tr[get_suc(x)].v),LF;break;
		}
	}
    return 0;
}
2024/1/26 17:03
加载中...