P3369 求调
  • 板块灌水区
  • 楼主Zq_water
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/10/8 13:28
  • 上次更新2023/11/2 14:56:51
查看原帖
P3369 求调
895435
Zq_water楼主2023/10/8 13:28
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;

int n,cnt,rt;
int son[maxn][2],fa[maxn],val[maxn],tot[maxn],siz[maxn];

int read();
void push_up(int u);
bool check(int u);
void rotate(int x);
void splay(int x,int k);
void insert(int x);
void del(int x);
int rnk(int u,int k);
int kth(int u,int k);
int Pre_and_Nxt(int x,int op);
void find(int x);

int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*f;
}
void push_up(int u){siz[u]=siz[son[u][0]]+siz[son[u][1]]+tot[u];}
bool check(int u){return u==son[fa[u]][1];}
void rotate(int x){
	int y=fa[x],z=fa[y],k=check(x);
	son[y][k]=son[x][k^1],fa[son[x][k^1]]=y;
	son[x][k^1]=y,fa[y]=x;
    fa[x]=z;
    if(z) son[z][son[z][1]==y]=x;
    push_up(x),push_up(y);
}
void splay(int x,int k){
	while(fa[x]!=k){
		int y=fa[x],z=fa[y];
		if(z!=k) check(x)^check(y)?rotate(x):rotate(y);
		rotate(x);
	}
	if(!k) rt=x;
}
void insert(int x){
	int u=rt,f=0;
	while(u&&val[u]!=x) f=u,u=son[u][val[u]<x];
	if(!u){
		u=++cnt;
		tot[u]=siz[u]=1;
		fa[u]=f,val[u]=x;
		if(f) son[f][val[f]<x]=cnt;
	}
	else tot[u]++;
	splay(u,0);
}

void del(int x){
	int pre=Pre_and_Nxt(x,0),nxt=Pre_and_Nxt(x,1);
	splay(pre,0),splay(nxt,pre);
	if(tot[son[nxt][0]]>1) tot[son[nxt][0]]--,splay(son[nxt][0],0);
	else son[nxt][0]=0;
	push_up(nxt),push_up(pre);
}

int rnk(int x){
	find(x);
	return siz[son[rt][0]];
}

int kth(int x){
	int u=rt;
	if(siz[u]<x) return 0;
	while(1){
		if(son[u][0]&&x<=siz[son[u][0]]) u=son[u][0];
		else if(siz[son[u][0]]+tot[u]<x){
			x-=(siz[son[u][0]]+tot[u]);
			u=son[u][1];
		}
		else{splay(u,0);return val[u];}
	}
}

int Pre_and_Nxt(int x,int op){
	find(x);
	if((!op&&val[rt]<x)||(op&&val[rt]>x)) return rt;
	int u=son[rt][op];
	while(son[u][!op]) u=son[u][!op];
	splay(u,0);	
	return val[u];
}

void find(int x){
	int u=rt;
	while(son[u][val[u]<x]&&val[u]!=x) u=son[u][val[x]<u];
	splay(u,0);
}

int main(){
	n=read();
	for(int i=1,op,x;i<=n;i++){
		op=read(),x=read();
		if(op==1) insert(x);
		if(op==2) del(x);
		if(op==3) printf("%d\n",rnk(x));
		if(op==4) printf("%d\n",kth(x));
		if(op==5) printf("%d\n",Pre_and_Nxt(x,0));
		if(op==6) printf("%d\n",Pre_and_Nxt(x,1));
	}
	return 0;
}
2023/10/8 13:28
加载中...