• 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
    ",v>now?-1:val[findkth(root,v)]);
    	}
    	printf("%d",all-now);
    	return 0;
    }
    

      

  • 相关阅读:
    计算三角形的周长和面积的类
    类的定义和继承
    简单类的定义和继承
    template <typename T>模板类定义
    字符串中取出数字字符串
    C++类定义 常量定义
    cogs1752[boi2007]mokia 摩基亚 (cdq分治)
    bzoj3262陌上花开 cdq分治入门题
    初入lambda表达式 (主要是c++11)
    空之境界
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1503.html
Copyright © 2020-2023  润新知