1503: [NOI2004]郁闷的出纳员

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

Description

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

Input

bzoj 1503郁闷的出纳员(splay)-LMLPHP

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

05-04 03:25