郁闷的出纳员(splay)

bzoj一直 runtime

codevs ac,表示无语。。。,应该是自己写炸了

2016.8.22更新

bzoj ac

#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=510005;
int ans,tot,mi,num,add,rt,pre;

int fa[N],ch[N][2],size[N],val[N],cnt[N];

void up(int i)
{
	size[i]=size[ch[i][0]]+size[ch[i][1]]+cnt[i];
}

void rotate(int x)
{
	int y=fa[x],z=fa[y],l,r;
	if (ch[y][0]==x) l=0;else l=1;r=l^1;
	if (z)
	if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;
	fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
	ch[y][l]=ch[x][r];ch[x][r]=y;
	up(y); 
}
void splay(int x,int k)
{
	int y,z;
	while (fa[x]!=k)
	{
		y=fa[x],z=fa[y];
		if (z!=k)
		if (ch[z][0]==y^ch[y][0]==x) rotate(x);else rotate(y);
		rotate(x);
	}
	if (k==0) rt=x;
	up(x);
}

void insert(int x)
{	
	if (rt==0)
	{
		rt=++tot;val[tot]=x;size[tot]=1;cnt[tot]=1;
		return ;
	}
	int now=rt;
	while (true)
	{
		size[now]++;
		if (val[now]==x)
		{
			cnt[now]++;
			return ;
		}
		int y=ch[now][x>val[now]];
		if (y==0)
		{
			tot++;
			val[tot]=x;
			cnt[tot]=1;
			size[tot]=1;
			fa[tot]=now;
			ch[now][x>val[now]]=tot;
			now=tot;
			break;
		}
		now=y;
	}
	splay(now,0);
}

void find_pre(int i,int x)
{
	if (i==0) return ;
	if (val[i]<x){pre=i;find_pre(ch[i][1],x);}
	else find_pre(ch[i][0],x); 
}

void work(int add)
{
	//if (add>=0) return ;
	int x=mi-add;
	
	pre=-1;
	find_pre(rt,x);
	if (pre==-1) return ;
	
	splay(pre,0);
	ans+=size[ch[pre][0]]+cnt[pre];
	rt=ch[pre][1];
	fa[ch[pre][1]]=0;
}

int find_kth(int i,int k)
{
	if (i==0) return -1;
	if (size[ch[i][1]]>=k) return find_kth(ch[i][1],k);
	if (size[ch[i][1]]+cnt[i]>=k) return val[i]+add;
	return find_kth(ch[i][0],k-size[ch[i][1]]-cnt[i]);
}

int main()
{
	int n;
	scanf("%d%d",&n,&mi);
	char s[3];
	
	while (n--)
	{
		int x;
		scanf("%s%d",s,&x);
		
		switch(s[0])
		{
			case 'I':
				if (x<mi) continue;
				insert(x-add);
			break;
			
			case 'A':
				add+=x;
			break;	
			
			case 'S':
				add-=x;
				work(add);
			break;	
			
			case 'F':
				printf("%d\n",find_kth(rt,x));
			break;	
		}
	}
	printf("%d",ans);
	return 0;	
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值