I命令的条数不超过100000 A命令和S命令的总条数不超过100 F命令的条数不超过100000 每次工资调整的调整量不超过1000 新员工的工资不超过100000
Treap......
第一次编Treap,Treap与SBT的区别就是Treap在maintain()中以key值判断是否需要旋转,而且Treap中所有都是单旋,写起来比SBT短一点。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 2000000
#define MAXT MAXN
#define INF 0x3f3f3f3f
struct Treap
{
int K[MAXT],V[MAXT],L[MAXT],R[MAXT],S[MAXT];
int root;
int topt;
Treap()
{
root=0;
topt=0;
}
void update(int now)
{
S[now]=S[L[now]]+S[R[now]]+1;
}
void r_rotate(int &now)
{
int t=L[now];
L[now]=R[t];update(now);
R[t]=now;update(t);
now=t;
}
void l_rotate(int &now)
{
int t=R[now];
R[now]=L[t];update(now);
L[t]=now;update(t);
now=t;
}
void maintain(int &now)
{
if (L[now] && K[now]<K[L[now]])
{
r_rotate(now);
}else if (R[now] && K[now]<K[R[now]])
{
l_rotate(now);
}
}
void Insert(int &now,int val)
{
if (!now)
{
now=++topt;
L[now]=R[now]=0;
S[now]=1;
K[now]=rand();
V[now]=val;
return ;
}
if (V[now]>val)
Insert(L[now],val);
else Insert(R[now],val);
update(now);
maintain(now);
}
void Delete(int &now)
{
if (!now)return ;
if (!L[now])
now=R[now];
else if (!R[now])
now=L[now];
else
{
r_rotate(now);
Delete(R[now]);
}
if (now)
{
update(now);
maintain(now);
}
}
int Adjust(int &now,int v)
{
if (!now)return 0;
int ret=0;
if (V[now]<v)
{
ret+=Adjust(L[now],v);
ret+=Adjust(R[now],v);
Delete(now);
ret++;
}else if (V[now]>=v)
{
ret+=Adjust(L[now],v);
}
if (now)
{
update(now);
maintain(now);
}
return ret;
}
int Qry_kth(int &now,int rk)
{
if (!now)
return -INF;
if (S[L[now]]+1==rk)
return V[now];
if (S[L[now]]+1<rk)
{
return Qry_kth(R[now],rk-S[L[now]]-1);
}else
{
return Qry_kth(L[now],rk);
}
}
void Scan(int now,int delta=0)
{
if (!now)
return ;
if (S[now]!=S[L[now]]+S[R[now]]+1)
throw 1;
if (K[now]<K[L[now]] || K[now]<K[R[now]])
throw 1;
Scan(L[now],delta);
printf("%d ",V[now]+delta);
Scan(R[now],delta);
}
}Tp;
int main()
{
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,m;
int i,j,k;
int base,delta;
scanf("%d%d\n",&n,&base);
delta=0;
int x,y,z;
char opt;
int tot=0;
for (i=0;i<n;i++)
{
scanf("%c%d\n",&opt,&x);
if (opt==‘I‘)
{
x-=delta;
if (x<base)
continue;
Tp.Insert(Tp.root,x);
}else if (opt==‘A‘)
{
delta+=x;
base-=x;
}else if (opt==‘S‘)
{
delta-=x;
base+=x;
tot+=Tp.Adjust(Tp.root,base);
}else if (opt==‘F‘)
{
x=Tp.S[Tp.root]-x+1;
y=Tp.Qry_kth(Tp.root,x);
if (y==-INF)
printf("-1\n");
else
printf("%d\n",y+delta);
}
}
printf("%d\n",tot);
}