萌新求调题
查看原帖
萌新求调题
291706
Unordered_OIer楼主2021/3/4 21:13

萌新刚学 Splay,样例输出

-1
-1
-1
0

甚至按照某篇题解对着改了一遍,还是一样 qwq。

求泥谷神犇们帮忙调一下......

#include<bits/stdc++.h>
#define N 300005
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
inline void write(ll x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
inline void writeln(ll x){write(x),putchar('\n');}
struct node{ll ch[2],p,cnt,sz,val;}tr[N];
//ch[2]:左右儿子,p:父节点,cnt:计数器(重数),sz:子树大小,val:节点权值
ll n,m,tot,rt,ans;
inline ll Son(ll u){return tr[tr[u].p].ch[1]==u;}//判断u是父亲的哪个(左/右)儿子
inline void pushup(ll u){tr[u].sz=tr[tr[u].ch[0]].sz+tr[tr[u].ch[1]].sz+tr[u].cnt;}//更新子树大小
inline void add(ll x){for(ll i=1;i<=tot;i++)tr[i].val+=x;}//加工资
inline void sub(ll x){for(ll i=1;i<=tot;i++)tr[i].val-=x;}//扣工资
inline void rotate(ll u){//旋转
	ll fa=tr[u].p,gfa=tr[fa].p;//父和爷爷
	ll flag=Son(u),son=tr[u].ch[flag^1];//哪个儿子(左/右),另一个儿子
	tr[fa].ch[flag]=son,tr[son].p=fa;//son变为fa的儿子
	tr[gfa].ch[Son(fa)]=u,tr[u].p=gfa;//u变为gfa的儿子
	tr[u].ch[flag^1]=fa,tr[fa].p=u;//fa变为u的另一个儿子
	pushup(fa),pushup(u);//更新u,fa的子树大小
}
inline void splay(ll u){//将u旋转到指定节点的儿子
	while(tr[u].p){
		ll fa=tr[u].p,gfa=tr[fa].p;
		if(gfa)Son(u)==Son(fa)?rotate(fa):rotate(u);
		rotate(u);
	}
	rt=u;
}
inline ll find(ll x,ll ans=0){//找最小>=x的数
	ll u=rt;
	while(x!=tr[u].val&&tr[u].ch[x>tr[u].val])u=tr[u].ch[x>tr[u].val];
	splay(rt);
	if(tr[rt].val>=x)return rt;
	while(tr[u].ch[0])u=tr[u].ch[0];
	return u;
}
inline void del(ll x){//删除<x的数
	ll u=find(x);
	splay(u);
	ans+=tr[tr[u].ch[0]].sz;
	tr[u].ch[0]=0;//splay后只删左子树
	pushup(u);
	sub(x);
}
inline void ins(ll x){//插入数
	if(x<m)return;
	ll u=rt,nxt=0;
	while(tr[u].val!=x&&u)nxt=u,u=tr[u].ch[x>tr[u].val];
	if(u)tr[u].cnt++;
	else {
		u=++tot;
		if(nxt)tr[nxt].ch[x>tr[nxt].val]=u;
		tr[u].p=nxt;
		tr[u].ch[0]=tr[u].ch[1]=0;
		tr[u].sz=tr[u].cnt=1;
		tr[u].val=x;//重置
	}
	splay(rt);
}
inline ll kth(ll k){//求k大
	if(k>=tr[rt].sz)return -1;
	k++;ll u=rt;
	while(1){
		if(tr[u].ch[1]&&k<=tr[tr[u].ch[1]].sz)u=tr[u].ch[1];
		else if(k>tr[tr[u].ch[1]].sz+tr[u].cnt){
			k-=tr[tr[u].ch[1]].sz-tr[u].cnt;
			u=tr[u].ch[0];
		}else return tr[u].val;
	}
}
int main(){
	n=read(),m=read();
	ins(inf);
	for(ll i=1;i<=n;i++){
		char op=getchar();
		ll x=read();
		if(op=='I')ins(x);
		if(op=='A')add(x);
		if(op=='S')del(x);
		if(op=='F')writeln(kth(x));
	}
	writeln(ans);
	return 0;
}
2021/3/4 21:13
加载中...