1503: [NOI2004]郁闷的出纳员

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 11759  Solved: 4163
[Submit][Status][Discuss]

Description

OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?

Input

Output

输出文件的行数为F命令的条数加一。对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。输出文件的最后一行包含一个整数,为离开公司的员工的总数。

Sample Input

9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2

Sample Output

10
20
-1
2

HINT

I命令的条数不超过100000 A命令和S命令的总条数不超过100 F命令的条数不超过100000 每次工资调整的调整量不超过1000 新员工的工资不超过100000

 
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100010
#define ls(x) tr[x].l
#define rs(x) tr[x].r
#define fa(x) tr[x].fa
using namespace std;
struct node
{
int l,r,fa,size,v;
};
node tr[N];
int n,m,tot,root,delta,sum; void PushUp(int x)
{
tr[x].size=tr[ls(x)].size+tr[rs(x)].size+;
} void zig(int x)
{
int y=fa(x);
int z=fa(y);
if(y==ls(z))ls(z)=x;
else rs(z)=x;
fa(x)=z,ls(y)=rs(x),fa(y)=x,fa(rs(x))=y,rs(x)=y;
PushUp(y),PushUp(x);
if(y==root)root=x;
} void zag(int x)
{
int y=fa(x);
int z=fa(y);
if(y==ls(z))ls(z)=x;
else rs(z)=x;
fa(x)=z,rs(y)=ls(x),fa(y)=x,fa(ls(x))=y,ls(x)=y;
PushUp(y),PushUp(x);
if(y==root)root=x;
} void Splay(int x,int d)
{
while(fa(x)!=d)
{
if(ls(fa(x))==x)zig(x);
else zag(x);
}
} void insert(int x)
{
if(!root)
{
root=++tot;
tr[tot].v=x,tr[tot].size=;
return ;
}
int p=root,z;
while(p)
{
z=p;
tr[p].size++;
if(x<tr[p].v)p=ls(p);
else p=rs(p);
}
if(x<tr[z].v)ls(z)=++tot;
else rs(z)=++tot;
tr[tot].v=x,tr[tot].size=,fa(tot)=z;
Splay(tot,);
} int del(int &x,int f)
{
if(!x)return ;
int k;
if(tr[x].v+delta<m)
{
k=del(rs(x),x)+tr[ls(x)].size+;
tr[rs(x)].size=tr[x].size-k;
x=rs(x),fa(x)=f;
}else
{
k=del(ls(x),x);
tr[x].size-=k;
}
return k;
} int query(int x,int k)
{
if(k<=tr[rs(x)].size)return query(rs(x),k);
if(k==tr[rs(x)].size+)return tr[x].v;
return query(ls(x),k-tr[rs(x)].size-);
} int main()
{
cin>>n>>m;
for(int i=;i<=n;i++)
{
char s[];
int x;
scanf("%s%d",s,&x);
if(s[]=='I'&&x>=m)insert(x-delta);
else if(s[]=='A')delta+=x;
else if(s[]=='S')delta-=x,sum+=del(root,);
else if(s[]=='F'&&x>tr[root].size)puts("-1");
else if(s[]=='F')printf("%d\n",query(root,x)+delta);
}
cout<<sum<<endl;
return ;
}

AC代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring> #define N 1000007 using namespace std;
int f[N],ch[N][],siz[N],cnt[N],key[N];
int lim,n,m,ans,tot,x,y,sz,root;char c; inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} inline void update(int x)
{
siz[x]=cnt[x];
if(ch[x][]) siz[x]+=siz[ch[x][]];
if(ch[x][]) siz[x]+=siz[ch[x][]];
} int pre()
{
int now=ch[root][];
while(ch[now][]) now=ch[now][];return now;
} int nex()
{
int now=ch[root][];
while(ch[now][]) now=ch[now][];return now;
} int getson(int x)
{
return ch[f[x]][]==x;
} void rorate(int x)
{
int fa=f[x],ffa=f[fa],k=getson(x);
ch[fa][k]=ch[x][k^];f[ch[fa][k]]=fa;
ch[x][k^]=fa;f[fa]=x;f[x]=ffa;
if(ffa)ch[ffa][ch[ffa][]==fa]=x;
update(fa);update(x);
} void splay(int x)
{
for(int fa;fa=f[x];rorate(x))
if(f[fa]) rorate(getson(x)==getson(fa)?fa:x);
root=x;
} int findpos(int x)
{
int now=root,ans=;
while()
{
if(x<key[now]) now=ch[now][];
else
{
ans+=ch[now][]?siz[ch[now][]]:;
if(x==key[now])
{
splay(now);return ans+;
}
ans+=cnt[now];now=ch[now][];
}
}
} int findx(int x)
{
int now=root;
while()
{
if(ch[now][]&&x<=siz[ch[now][]]) now=ch[now][];
else
{
int tmp=(ch[now][]?siz[ch[now][]]:)+cnt[now];
if(x<=tmp) return key[now]+tot;
x-=tmp;now=ch[now][];
}
}
} void clear(int x)
{
ch[x][]=ch[x][]=cnt[x]=siz[x]=key[x]=f[x]=;
} void creat(int x)
{
sz=sz+;key[sz]=x;cnt[sz]=siz[sz]=;
ch[sz][]=ch[sz][]=f[sz]=;
} void insert(int x)
{
if(!root) creat(x),root=sz;
else
{
int now=root,fa=;
while()
{
if(key[now]==x)
{
cnt[now]++;siz[now]++;splay(now);
break;
}
fa=now;now=ch[fa][x>key[fa]];
if(!now)
{
creat(x);f[sz]=fa;ch[fa][x>key[fa]]=sz;
splay(sz);break;
}
}
}
} void del(int x)
{
//int t=findpos(x);
if(cnt[root]>)
{
cnt[root]--;siz[root]--;return;
}
if(!ch[root][]&&!ch[root][])
{
clear(root);root=;return;
}
if(!ch[root][])
{
int tmp=root;root=ch[root][];f[root]=;
clear(tmp);return;
}
if(!ch[root][])
{
int tmp=root;root=ch[root][];f[root]=;
clear(tmp);return;
}
int pre1=pre(),tmp=root;splay(pre1);
ch[root][]=ch[tmp][];f[ch[tmp][]]=root;
clear(tmp);update(root);
} inline void del_tree()
{
f[ch[root][]]=;
siz[root]-=siz[ch[root][]];
ch[root][]=;
} int main()
{
n=read();lim=read();
for(int i=;i<=n;i++)
{
cin>>c;x=read();
if(c=='I'&&x>=lim)insert(x-tot);
if(c=='A') tot+=x;
if(c=='S')
{
tot-=x;
insert(lim-tot);ans+=ch[root][]?siz[ch[root][]]:;
del_tree();del(key[root]);
}
if(c=='F')
{
if(siz[root]<x) printf("-1\n");
else printf("%d\n",findx(siz[root]-x+));
}
}
printf("%d\n",ans);
return ;
}

洛谷A,bzoj RE

bzoj 1503郁闷的出纳员(splay)的更多相关文章

  1. [BZOJ 1503]郁闷的出纳员(fhq treap)

    [BZOJ 1503]郁闷的出纳员 题面 第一行有两个非负整数n和min.n表示下面有多少条命令,min表示工资下界. 接下来的n行,每行表示一条命令.命令可以是以下四种之一: 名称 格式 作用 I命 ...

  2. 洛谷 1486/BZOJ 1503 郁闷的出纳员

    1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 13866  Solved: 5069[Submit][Stat ...

  3. BZOJ 1503 郁闷的出纳员 (treap)

    1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 13370  Solved: 4808[Submit][Stat ...

  4. BZOJ 1503 郁闷的出纳员(splay)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 题意:给出一个数列(初始为空),给出一个最小值Min,当数列中的数字小于Min时自动 ...

  5. BZOJ 1503 郁闷的出纳员(平衡树)(NOI 2004)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作 ...

  6. BZOJ 1503 郁闷的出纳员

    Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...

  7. BZOJ[NOI2004]郁闷的出纳员 | Splay板子题

    题目: 洛谷也能评测....还有我wa了10多次的记录233 题解: 不要想得太复杂,搞一个全局变量记录一下工资的改变量Delta,这样可以等询问的时候就输出val+Delta,然后插入的时候插入x- ...

  8. BZOJ 1503: [NOI2004]郁闷的出纳员 splay

    1503: [NOI2004]郁闷的出纳员 Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作 ...

  9. NOI2004 郁闷的出纳员 Splay

    郁闷的出纳员 [问题描述] OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常, ...

随机推荐

  1. OpenCV:使用OpenCV3随机森林进行统计特征多类分析

    原文链接:在opencv3中的机器学习算法练习:对OCR进行分类 本文贴出的代码为自己的训练集所用,作为参考.可运行demo程序请拜访原作者. CNN作为图像识别和检测器,在分析物体结构分布的多类识别 ...

  2. Lazarus 1.44升级到1.6 UTF8处理发生变化了

    首先这里真的要强调一下,由于Freepascal升级到3.0后,FPC的内部将整个代码处理由AnsiString改为了UTF8编码(RTL with default codepage UTF-8). ...

  3. mysql zip版本如何安装

    1.下载mysqlzip包并解压到D:\javadeveloper\mysql-5.6.24-winx642.配置环境变量在path中添加路径 D:\javadeveloper\mysql-5.6.2 ...

  4. java中关于数组的初始化

  5. DOM节点的获取

      document.getElementById();//id名,在实际开发中较少使用,选择器中多用class  id一般只用在顶级层存在 不能太过依赖id document.getElements ...

  6. Labview学习笔记(三)

    一.数据 1.数值控件 (1)数值控件 根据不同的模拟状态,放置不同控件 (2)显示格式 为了程序显示,需要设置数值型控件的表示法.数值范围.显示格式等属性. 一般来说,长度越长,则可以表示的数值范围 ...

  7. Promise嵌套问题/async await执行顺序

    /* 原则: 执行完当前promise, 会把紧挨着的then放入microtask队尾, 链后面的第二个then暂不处理分析, */ 一. new Promise((resolve, reject) ...

  8. POJ-2135-Farm Tour(最大费用最小流)模板

    Farm Tour POJ - 2135 When FJ's friends visit him on the farm, he likes to show them around. His farm ...

  9. Django CBV视图解决csrf认证

    urls.py from django.conf.urls import url from appxx import views urlpatterns = [ url(r"^$" ...

  10. BZOJ 1724 USACO 2006 Nov. 切割木板

    倒过来的合并果子? 做法与合并果子一样 维护一个小根堆,每次取出最小的两个数进行合并 #include<cstdio> #include<algorithm> #include ...