題意:整體加減+加點删點,查詢第k大。
splay維護樹即可。(話說第一次寫splay,完全不會)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#define N 100009
#define ll long long
#define inf 0x7fffffff
using namespace std;
int n,Min,root,val[N],size[N],son[N][2],father[N],cnt=0,delta=0,ans=0;
char ch;
int x;
void up(int x)
{
size[x]=size[son[x][0]]+size[son[x][1]]+1;
}
void rotate(int x)
{
int y=father[x],k=(son[y][0]==x);
son[y][!k]=son[x][k];
father[son[y][!k]]=y;
father[x]=father[y];
if (father[y]) son[father[y]][son[father[y]][1]==y]=x;
son[x][k]=y;
father[y]=x;
up(y);
}
void sy(int x,int g)
{
for (int y;(y=father[x])!=g;rotate(x))
if (father[y]) rotate((x==son[y][0])==(y==son[father[y]][0])?y:x);
up(x);
if (!g) root=x;
}
void newnode(int &x,int fa,int z)
{
x=++cnt;
father[x]=fa;
size[x]=1;
val[x]=z;
son[x][0]=son[x][1]=0;
}
void ins(int a)
{
if (!root)
{
root=++cnt;
val[root]=a;
size[root]=1;
return;
}
int x=root;
while (son[x][val[x]<a]) size[x]++,x=son[x][val[x]<a];
newnode(son[x][val[x]<a],x,a);
sy(son[x][val[x]<a],0);
}
int find(int x,int y)
{
if (y<=size[son[x][1]]) return find(son[x][1],y);
if (y==size[son[x][1]]+1) return val[x];
return find(son[x][0],y-size[son[x][1]]-1);
}
int dec(int &x,int fa)
{
if (!x) return 0;
int k;
if (val[x]+delta<Min)
{
k=dec(son[x][1],x)+size[son[x][0]]+1;
size[son[x][1]]=size[x]-k;
x=son[x][1];
father[x]=fa;
}
else
{
k=dec(son[x][0],x);
size[x]-=k;
}
return k;
}
int main()
{
scanf("%d%d",&n,&Min);
root=0;
for (int i=1;i<=n;i++)
{
while (ch=getchar(),ch!='A'&&ch!='I'&&ch!='S'&&ch!='F');
scanf("%d",&x);
switch (ch)
{
case 'I':
if (x>=Min) ins(x-delta);
break;
case 'A':
delta+=x;
break;
case 'S':
delta-=x;
ans+=dec(root,0);
break;
case 'F':
printf("%d\n",x<=size[root]?find(root,x)+delta:-1);
}
}
printf("%d\n",ans);
return 0;
}