BZOJ1503 [NOI2004]郁闷的出纳员 splay

原文链接http://www.cnblogs.com/zhouzhendong/p/8086240.html


题目传送门 - BZOJ1503


题意概括

如果某一个员工的工资低于了min,那么,他会立即离开,并且一定不会回来了。

最后还要输出一个整数,表示离开公司的员工的总数。


题解

  还是splay裸题。

  加一个懒标记就可以了。

  注意,如果一个人还没有进入公司就因为工资太少而走了,不计入离开公司的员工数中


代码

 

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=100005;
int fa[N],son[N][2],add[N],val[N],size[N],total,root;
void spt_clear(){
	total=root=0;
	memset(fa,0,sizeof fa);
	memset(son,0,sizeof son);
	memset(add,0,sizeof add);
}
void pushup(int x){
	size[x]=size[son[x][0]]+size[son[x][1]]+1;
}
void pushson(int x,int v){
	add[x]+=v,val[x]+=v;
}
void pushdown(int x){
	for (int i=0;i<2;i++)
	if (son[x][i])
		pushson(son[x][i],add[x]);
	add[x]=0;
}
void pushadd(int x){
	if (fa[x])
		pushadd(fa[x]);
	pushdown(x);
}
int wson(int x){
	return son[fa[x]][1]==x;
}
void rotate(int x){
	if (!fa[x])
		return;
	int y=fa[x],z=fa[y],L=wson(x),R=L^1;
	if (z)
		son[z][wson(y)]=x;
	fa[x]=z,fa[y]=x,fa[son[x][R]]=y;
	son[y][L]=son[x][R],son[x][R]=y;
	pushup(y),pushup(x);
}
void splay(int x,int rt){
	if (!x)
		return;
	if (!rt)
		root=x;
	pushadd(x);
	for (int y=fa[x];fa[x];rotate(x),y=fa[x])
		if (fa[y])
			rotate(wson(x)==wson(y)?y:x);
}
void insert(int v,int &x,int pre){
	pushdown(x);
	if (x)
		return insert(v,son[x][v>val[x]],x);
	fa[x=++total]=pre,val[x]=v,size[x]=1;
	splay(x,0);
}
int findkth(int x,int k){
	pushdown(x);
	if (size[son[x][1]]+1==k)
		return x;
	if (size[son[x][1]]>=k)
		return findkth(son[x][1],k);
	else
		return findkth(son[x][0],k-size[son[x][1]]-1); 
}
int findpre(int v,int rt){
	if (!rt)
		return 0;
	pushdown(rt);
	if (v>val[rt]){
		int x=findpre(v,son[rt][1]);
		return x?x:rt;
	}
	return findpre(v,son[rt][0]);
}
int findpre(int v){
	int res=findpre(v,root);
	splay(res,0);
	return res;
}
int n,Min;
int main(){
	scanf("%d%d",&n,&Min);
	spt_clear();
	int all=0,now=0;
	for (int i=1;i<=n;i++){
		char op[2];
		int v;
		scanf("%s%d",op,&v);
		if (op[0]=='I'){
			if (v<Min)
				continue;
			insert(v,root,0);
			all++;
			now++;
		}
		if (op[0]=='A')
			pushson(root,v);
		if (op[0]=='S'){
			pushson(root,-v);
			int wc=findpre(Min);
			if (!wc)	
				continue;
			int rt=root;
			now-=size[son[rt][0]]+1;
			fa[root=son[rt][1]]=0;
			son[rt][1]=0;
		}
		if (op[0]=='F')
			printf("%d\n",v>now?-1:val[findkth(root,v)]);
	}
	printf("%d",all-now);
	return 0;
}

 

  

 

posted @ 2017-12-22 15:31  zzd233  阅读(399)  评论(0编辑  收藏  举报