人力资源管理
Time Limit:10000MS Memory Limit:65536K
Total Submit:230 Accepted:141
Case Time Limit:1000MS
Description
某公司有n个员工,每个员工有一个工作能力值(该值为60000以内的自然数)。
Tom是公司人力资源部门的主管,他可以进行如下3种操作:
1.Tom为公司招聘了一个能力值为x的新员工
2.Tom为公司辞退了一个能力值为y的员工
3.Tom要查出在所有员工能力值由高到低的排名中,能力值大于W的员工的人数
Input
第一行两个整数n,m 表示有n个员工,和tom的m项工作
接下来一行,n个整数,表示n个员工的能力值
接下来m行,每行有两个整数a,b(1<=b<=60000)。
a==1 表示招聘了一个能力值为b的新员工
a==2 表示辞退了一个能力值为b的员工(若没有能力值为b的员工,则该操作无效)
a==3 表示查出能力值>b的员工的个数,并输出结果
Output
若干行,每行一个整数,表示输入中所有a==3的操作的结果。
Sample Input
样例输入1:
6 5
9 4 6 2 3 5
1 7
1 10
3 6
2 9
3 6
样例输入2:
4 4
4 1 2 5
1 3
3 3
2 4
3 1
Sample Output
样例输出1:
3
2
样例输出2:
2
3
Hint
n,m<=100000
分析:
题中给出,每个员工的能力值在60000以内,我们可以建立一个表示区间[1,60001]的线段树。
线段树的节点struct node{ int a, b, L, R, Cnt; };
Cnt记录该出现在区间[a,b]中的数字个数
查询能力值大于y的人的个数即查询能力值在y+1到60001的人数即可
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=60001;
inline void _read(int &x){
char t=getchar();bool sign=true;
while(t<'0'||t>'9')
{if(t=='-')sign=false;t=getchar();}
for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';
if(!sign)x=-x;
}
int n,m,a,b,s[maxn+2],tot;
struct wk{int left,right,a,b,v;}tree[2*maxn];
void insert(int x,int y){
int r=++tot;
tree[r].a=x;tree[r].b=y;
if(x<y){
tree[r].left=tot+1;
insert(x,(x+y)/2);
tree[r].right=tot+1;
insert((x+y)/2+1,y);
tree[r].v=tree[tree[r].left].v+tree[tree[r].right].v;
}
else tree[r].v=s[x];
}
void change(int r){
if(b==tree[r].a&&b==tree[r].b){
if(a==1)tree[r].v++;
else if(tree[r].v)tree[r].v--;
return;
}
if(tree[r].left&&tree[tree[r].left].a<=b&&tree[tree[r].left].b>=b)
change(tree[r].left);
if(tree[r].right&&tree[tree[r].right].a<=b&&tree[tree[r].right].b>=b)
change(tree[r].right);
tree[r].v=tree[tree[r].left].v+tree[tree[r].right].v;
}
int getnum(int r){
if(tree[r].a>b&&tree[r].b<=maxn)return tree[r].v;
int total=0;
if(tree[r].left&&tree[tree[r].left].b>b)
total+=getnum(tree[r].left);
if(tree[r].right&&tree[tree[r].right].b>b)
total+=getnum(tree[r].right);
return total;
}
int main(){
_read(n);_read(m);
for(int i=1;i<=n;i++){
_read(a);
s[a]++;
}
insert(0,maxn);
for(int i=1;i<=m;i++){
_read(a);_read(b);
if(a==1||a==2)change(1);
else printf("%d\n",getnum(1));
}
}