传送门1
传送门2
写在前面:代码一长,细节问题就多了起来,还是需要熟练啊
思路:插入,删除,查第k大的splay,再加一个改值函数,因为改动工资的操作很少(才100),所以直接暴力从根开始往下改,小于工资下限就入队,最后把队里的元素删除就行
注意:一开始的工资就小于下限的人不会进公司,但也不计入离开公司的人数,切记!
代码:
#include<bits/stdc++.h>
using namespace std;
int root,n,minn,tot,ans,x;
char ch;
queue<int> q;
struct os
{
int occ,data,fa,sz,ch[2];
}a[100100];
void ct(int now)
{
a[now].sz=a[now].occ+a[a[now].ch[0]].sz+a[a[now].ch[1]].sz;
}
void made(int x)
{
a[++tot].data=x;
a[tot].occ=a[tot].sz=1;
}
void rorate(int now,bool x)
{
int pa=a[now].fa;
a[a[now].fa].ch[x^1]=a[now].ch[x];
if (a[now].ch[x])a[a[now].ch[x]].fa=pa;
a[now].fa=a[pa].fa;
if (a[pa].fa)
{
if (a[a[pa].fa].ch[0]==pa) a[a[pa].fa].ch[0]=now;
else a[a[pa].fa].ch[1]=now;
}
a[pa].fa=now;
a[now].ch[x]=pa;
ct(pa);
ct(now);
}
void splay(int now,int goal)
{
int pa;
while (a[now].fa!=goal)
{
pa=a[now].fa;
if (a[pa].fa==goal)
{
if (a[pa].ch[0]==now) rorate(now,1);
else rorate(now,0);
}
else if (a[a[pa].fa].ch[0]==pa)
{
if (a[pa].ch[0]==now) rorate(pa,1);
else rorate(now,0);
rorate(now,1);
}
else
{
if (a[pa].ch[1]==now) rorate(pa,0);
else rorate(now,1);
rorate(now,0);
}
}
if (!goal) root=now;
}
void insert(int x)
{
if (!root) {made(x);root=tot;return;}
int now=root,flag=1;
while (flag)
{
a[now].sz++;
if (a[now].data==x){a[now].occ++;splay(now,0);return;}
else if (a[now].data>x)
{
if (!a[now].ch[0]) made(x),a[now].ch[0]=tot,a[tot].fa=now,flag=0;
else now=a[now].ch[0];
}
else
{
if (!a[now].ch[1]) made(x),a[now].ch[1]=tot,a[tot].fa=now,flag=0;
else now=a[now].ch[1];
}
}
splay(tot,0);
}
void update(int now,int x)
{
if (!now) return;
a[now].data+=x;
if (a[now].data<minn) q.push(now);
update(a[now].ch[0],x);
update(a[now].ch[1],x);
}
int Kth(int k)
{
if (k<=0) return 0;
int now=root;
while (now)
{
if (a[a[now].ch[1]].sz<k&&a[a[now].ch[1]].sz+a[now].occ>=k) break;
if (a[a[now].ch[1]].sz>=k) now=a[now].ch[1];
else k-=(a[a[now].ch[1]].sz+a[now].occ),now=a[now].ch[0];
}
if (now) splay(now,0);
return now;
}
int find_max(int now)
{
if (!now) return 0;
while (now)
{
if (!a[now].ch[1]) return now;
else now=a[now].ch[1];
}
}
bool del(int now)
{
if (!now) return 0;
splay(now,0);
if (!a[now].ch[0]&&!a[now].ch[1]) root=0;
else if (!a[now].ch[1])
{
root=a[now].ch[0];
a[a[now].ch[0]].fa=0;
}
else if (!a[now].ch[0])
{
root=a[now].ch[1];
a[a[now].ch[1]].fa=0;
}
else
{
splay(find_max(a[now].ch[0]),root);
root=a[now].ch[0];
a[a[now].ch[0]].fa=0;
a[a[now].ch[1]].fa=a[now].ch[0];
a[a[now].ch[0]].ch[1]=a[now].ch[1];
ct(a[now].ch[0]);
}
return 1;
}
main()
{
scanf("%d%d",&n,&minn);
a[0].data=-1;
while (n--)
{
ch=getchar();
while (ch!='I'&&ch!='A'&&ch!='S'&&ch!='F') ch=getchar();
scanf("%d",&x);
if (ch=='I')
{
if (x>=minn) insert(x);
}
else if (ch=='A') update(root,x);
else if (ch=='S')
{
update(root,-x);
while (!q.empty())
ans+=a[q.front()].occ,
del(q.front()),
q.pop();
}
else printf("%d\n",a[Kth(x)].data);
}
printf("%d",ans);
}