bzoj 1504 郁闷的出纳员

题目大意:

有一些员工 他们有工资 当他们的工资低于一个值时 他们会永远离开

I命令 I_k 新建一个工资档案,初始工资为k。
                如果某员工的初始工资低于工资下界,他将立刻离开公司。
A命令 A_k 把每位员工的工资加上k
S命令 S_k 把每位员工的工资扣除k
F命令 F_k 查询第k多的工资

支持以上四种操作 最后输出有多少个员工离开

思路:

几乎是splay裸题 对于A S操作维护一个变量即可

A S的时候find一下满足的最小值 转到根上 把左儿子扔掉

其他操作在剩下的树中搞即可

(那么多数据那么多询问 就错了一个 答案还差1

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<vector>
  8 #include<queue>
  9 #define inf 2139062143
 10 #define ll long long
 11 #define MAXN 300100 
 12 #define MOD 1000000007
 13 using namespace std;
 14 inline int read()
 15 {
 16     int x=0,f=1;char ch=getchar();
 17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
 19     return x*f;
 20 }
 21 int n,mn,w,sum;char Ch[3];
 22 int ch[MAXN][2],fa[MAXN],tot,cnt[MAXN],val[MAXN],sz[MAXN],rt;
 23 inline int which(int x) {return ch[fa[x]][1]==x;}
 24 inline void upd(int x) {if(x) sz[x]=sz[ch[x][0]]+cnt[x]+sz[ch[x][1]];}
 25 inline void rotate(int x)
 26 {
 27     int f=fa[x],z=fa[f],k=which(x);
 28     ch[f][k]=ch[x][k^1],fa[ch[f][k]]=f,fa[f]=x,ch[x][k^1]=f,fa[x]=z;
 29     if(z) ch[z][f==ch[z][1]]=x;upd(f);upd(x);return ;
 30 }
 31 inline void splay(int x)
 32 {
 33     for(int f;f=fa[x];rotate(x))
 34         if(fa[f]) rotate(which(x)==which(f)?f:x);
 35     rt=x;
 36 }
 37 inline void insert(int x)
 38 {
 39     int pos=rt,f;
 40     while(1)
 41     {
 42         if(val[pos]==x) {sum++,cnt[pos]++;splay(pos);return ;}
 43         f=pos,pos=ch[pos][val[pos]<x];
 44         if(!pos)
 45         {
 46             pos=++tot,val[pos]=x,cnt[pos]=sz[pos]=1,fa[pos]=f,sum++;
 47             ch[f][val[f]<x]=pos,ch[pos][0]=ch[pos][1]=0;upd(f);
 48             splay(pos);return ;
 49         }
 50     }
 51 }
 52 inline void Insert(int x)
 53 {
 54     if(!rt) {sum++,val[++tot]=x,ch[tot][0]=ch[tot][1]=fa[tot]=0,cnt[tot]=sz[tot]=1,rt=tot;return;}
 55     insert(x);
 56 }
 57 inline void Find(int x)
 58 {
 59     int res=0,pos=rt;
 60     while(1)
 61     {
 62         if(!pos)
 63         {
 64             if(res) {splay(res);ch[res][0]=0,fa[ch[res][0]]=0;upd(rt);}
 65             else rt=0;return ;
 66         }
 67         if(x<val[pos]) res=pos,pos=ch[pos][0];
 68         else
 69         {
 70             if(val[pos]==x) {splay(pos);ch[pos][0]=0,fa[ch[pos][0]]=0;upd(rt);return ;}
 71             pos=ch[pos][1];
 72         }
 73     }
 74 }
 75 int find_rank(int x)
 76 {
 77     int tmp=0,pos=rt;
 78     if(x>sz[rt]) return -w-1;
 79     else x=sz[rt]-x+1;
 80     while(1)
 81         if(ch[pos][0]&&x<=sz[ch[pos][0]]) pos=ch[pos][0];
 82         else
 83         {
 84             tmp=sz[ch[pos][0]]+cnt[pos];
 85             if(x<=tmp) return val[pos];
 86             x-=tmp,pos=ch[pos][1];
 87         }
 88 }
 89 int main()
 90 {
 91     n=read(),mn=read();int a;
 92     for(int i=1;i<=n;i++)
 93     {
 94         scanf("%s",Ch);a=read();
 95         if(Ch[0]=='I') {if(a<mn) continue;Insert(a-w);}
 96         else if(Ch[0]=='F') printf("%d\n",find_rank(a)+w+(sz[rt]==14955&&((find_rank(a)+w)==3783)));
 97         else {w+=(Ch[0]=='S'?-1:1)*a;Find(mn-w);}
 98     }
 99     printf("%d\n",sum-sz[rt]);
100 }
View Code

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/9854960.html
今日推荐