您的位置:首页 > 其它

bzoj 1503郁闷的出纳员(splay)

2017-06-09 21:12 281 查看

1503: [NOI2004]郁闷的出纳员

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

Description

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

Input

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>

#define N 1000007

using namespace std;
int f
,ch
[2],siz
,cnt
,key
;
int lim,n,m,ans,tot,x,y,sz,root;char c;

inline int read()
{
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}

inline void update(int x)
{
siz[x]=cnt[x];
if(ch[x][0]) siz[x]+=siz[ch[x][0]];
if(ch[x][1]) siz[x]+=siz[ch[x][1]];
}

int pre()
{
int now=ch[root][0];
while(ch[now][1]) now=ch[now][1];return now;
}

int nex()
{
int now=ch[root][1];
while(ch[now][0]) now=ch[now][0];return now;
}

int getson(int x)
{
return ch[f[x]][1]==x;
}

void rorate(int x)
{
int fa=f[x],ffa=f[fa],k=getson(x);
ch[fa][k]=ch[x][k^1];f[ch[fa][k]]=fa;
ch[x][k^1]=fa;f[fa]=x;f[x]=ffa;
if(ffa)ch[ffa][ch[ffa][1]==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=0;
while(1)
{
if(x<key[now]) now=ch[now][0];
else
{
ans+=ch[now][0]?siz[ch[now][0]]:0;
if(x==key[now])
{
splay(now);return ans+1;
}
ans+=cnt[now];now=ch[now][1];
}
}
}

int findx(int x)
{
int now=root;
while(1)
{
if(ch[now][0]&&x<=siz[ch[now][0]]) now=ch[now][0];
else
{
int tmp=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now];
if(x<=tmp) return key[now]+tot;
x-=tmp;now=ch[now][1];
}
}
}

void clear(int x)
{
ch[x][0]=ch[x][1]=cnt[x]=siz[x]=key[x]=f[x]=0;
}

void creat(int x)
{
sz=sz+1;key[sz]=x;cnt[sz]=siz[sz]=1;
ch[sz][0]=ch[sz][1]=f[sz]=0;
}

void insert(int x)
{
if(!root) creat(x),root=sz;
else
{
int now=root,fa=0;
while(1)
{
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]>1)
{
cnt[root]--;siz[root]--;return;
}
if(!ch[root][0]&&!ch[root][1])
{
clear(root);root=0;return;
}
if(!ch[root][0])
{
int tmp=root;root=ch[root][1];f[root]=0;
clear(tmp);return;
}
if(!ch[root][1])
{
int tmp=root;root=ch[root][0];f[root]=0;
clear(tmp);return;
}
int pre1=pre(),tmp=root;splay(pre1);
ch[root][1]=ch[tmp][1];f[ch[tmp][1]]=root;
clear(tmp);update(root);
}

inline void del_tree()
{
f[ch[root][0]]=0;
siz[root]-=siz[ch[root][0]];
ch[root][0]=0;
}

int main()
{
n=read();lim=read();
for(int i=1;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][0]?siz[ch[root][0]]:0;
del_tree();del(key[root]);
}
if(c=='F')
{
if(siz[root]<x) printf("-1\n");
else printf("%d\n",findx(siz[root]-x+1));
}
}
printf("%d\n",ans);
return 0;
}


洛谷A,bzoj RE
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: