N个操作,remove x,在列表中删除一个值为x的数;add x向列表中添加一个值为x的数。每次操作后,将列表排序,输出中位数,如果删除之后为空,输出Empty,删除操作非法的话,输出Wrong!。实质还是在线求整个区间的第k大数了,可以用treap来维护,每次操作后查一下中间位置的数或者是中间两个数,求个平均值就行,删除的时候如果删到了0节点还是没找到要删的数,就返回false表示删除非法。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=200000+1000;
const ll inf=1LL<<44;
int ch[maxn][2],counts[maxn],r[maxn],size[maxn],tot,root;
ll val[maxn];
struct TREAP
{
void newnode(int &rt,ll v)
{
rt=++tot;
val[rt]=v;
ch[rt][0]=ch[rt][1]=0;
counts[rt]=size[rt]=1;
r[rt]=rand();
}
inline void pushup(int rt)
{
size[rt]=size[ch[rt][0]]+size[ch[rt][1]]+counts[rt];
}
void rotate(int &x,int kind)
{
int y=ch[x][kind^1];
ch[x][kind^1]=ch[y][kind];
ch[y][kind]=x;
pushup(x);
pushup(y);
x=y;
}
void insert(int &rt,ll v)
{
if(rt==0)
{
newnode(rt,v);
return ;
}
if(v==val[rt]) counts[rt]++;
else
{
int kind=(v>val[rt]);
insert(ch[rt][kind],v);
if(r[ch[rt][kind]]<r[rt])
rotate(rt,kind^1);
}
pushup(rt);
}
ll select(int rt,int k)
{
if(size[ch[rt][0]]>=k) return select(ch[rt][0],k);
if(size[ch[rt][0]]+counts[rt]>=k) return val[rt];
return select(ch[rt][1],k-size[ch[rt][0]]-counts[rt]);
}
bool remove(int &rt,ll v)
{
bool res=true;
if (rt==0) return false;
if(val[rt]==v)
{
if(counts[rt]>1)
counts[rt]--;
else if(!ch[rt][0]&&!ch[rt][1])
{rt=0;return true;}
else
{
int kind=r[ch[rt][0]]<r[ch[rt][1]];
rotate(rt,kind);
remove(rt,v);
}
res=true;
}
else res=remove(ch[rt][v>val[rt]],v);
pushup(rt);
return res;
}
void init()
{
ch[0][0]=ch[0][1]=0;
size[0]=counts[0]=val[0]=0;
tot=root=0;
r[0]=(1LL<<31)-1;
newnode(root,inf);
}
}treap;
int n,m,k;
int num[maxn];
char cmd[22];
int x;
ll y,z;
int main()
{
int tt;
// freopen("in.txt","r",stdin);
scanf("%d",&tt);
while(tt--)
{
treap.init();
scanf("%d",&n);
for (int i=1; i<=n; i++)
{
scanf("%s",cmd);
scanf("%d",&x);
if (cmd[0]=='r')
{
if (size[root]==1)
{
puts("Wrong!");
}
else
{
if (!treap.remove(root,x))
{
puts("Wrong!");
continue;
}
int tol=size[root]-1;
if (tol==0) puts("Empty!");
else
if (tol&1)
{
y=treap.select(root,(tol+1)>>1);
printf("%lld\n",y);
}
else
{
y=treap.select(root,tol>>1);
z=treap.select(root,(tol>>1)+1);
if ((y+z)&1)printf("%.1lf\n",(double)(y+z)/2.0);
else printf("%lld\n",(y+z)/2ll);
}
}
}
else
{
treap.insert(root,x);
int tol=size[root]-1;
if (tol&1)
{
y=treap.select(root,(tol+1)>>1);
printf("%lld\n",y);
}
else
{
y=treap.select(root,tol>>1);
z=treap.select(root,(tol>>1)+1);
if ((y+z)&1)printf("%.1lf\n",(double)(y+z)/2.0);
else printf("%lld\n",(y+z)/2ll);
}
}
}
}
return 0;
}