线段树
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=100010;
const int mod=5;
int sum[maxn<<2]; //区间个数
ll ans[maxn<<2][mod]; //区间模i的和
int x[maxn]; //原数列
int key[maxn]; //重组数列
int flag; //增减标记
char op[maxn][10]; //操作符
void pushup(int rt) //更新ans[rt]
{
int i;
for(i=0;i<mod;i++)
{
ans[rt][i]=ans[rt<<1][i]+ans[rt<<1|1][(i-sum[rt<<1]%mod+mod)%mod];
}
}
void update(int pos,int l,int r,int rt) //更新
{
sum[rt]+=flag*2-1;
if(l==r)
{
ans[rt][0]=flag*key[pos];
return ;
}
int m=(l+r)>>1;
if(pos<=m)
{
update(pos,l,m,rt<<1);
}
else
{
update(pos,m+1,r,rt<<1|1);
}
pushup(rt);
}
void build(int l,int r,int rt) //建树
{
sum[rt]=0;
int i;
for(i=0;i<mod;i++)
{
ans[rt][i]=0;
}
if(l==r)
{
return ;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
}
int main()
{
int n,i;
while(~scanf("%d",&n))
{
int tot,sets;
tot=sets=0;
for(i=0;i<n;i++)
{
scanf("%s",op[i]);
if(op[i][0]=='a' || op[i][0]=='d')
{
scanf("%d",&x[i]);
key[tot++]=x[i];
}
}
if(tot>0)
{
sort(key,key+tot);
tot=unique(key,key+tot)-key; //删除相邻的重复元素
build(1,tot,1);
}
int pos;
for(i=0;i<n;i++)
{
if(op[i][0]=='a')
{
pos=lower_bound(key,key+tot,x[i])-key; //找到某个值的第一个出现
flag=1;
sets++;
update(pos,1,tot,1);
}
else if(op[i][0]=='d')
{
pos=lower_bound(key,key+tot,x[i])-key;
flag=0;
sets--;
update(pos,1,tot,1);
}
else
{
if(sets)
{
printf("%I64d\n",ans[1][2]);
}
else
{
printf("0\n");
}
}
}
}
return 0;
}