线段树
每个区间记录该区间内sum[0...4],在区间合并用时注意右区间需要用上左区间的所含元素个数。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100100
typedef long long ll;
using namespace std;
struct Point{
int l,r;
int num;//number in the interval
ll sum[5];//sum of the asked number in the interval
}tree[N*3];
int sel[N],pn[N],px[N];
void build(int s,int t,int id){
tree[id].l=s,tree[id].r=t,tree[id].num=0;
for(int i=0;i<5;i++)tree[id].sum[i]=0;
if(s!=t){
int mid=(s+t)>>1;
build(s,mid,id<<1);
build(mid+1,t,id<<1|1);
}
}
void insert(int pos,int number,int inc,int id){
int i;
if(tree[id].l==tree[id].r){
tree[id].num+=inc;
tree[id].sum[1]+=number;
return ;
}
int mid=(tree[id].l+tree[id].r)>>1;
if(pos<=mid)insert(pos,number,inc,id<<1);
else if(pos>mid)insert(pos,number,inc,id<<1|1);
tree[id].num=tree[id<<1].num+tree[id<<1|1].num;
for(i=0;i<5;i++)
tree[id].sum[i]=tree[id<<1].sum[i]+tree[id<<1|1].sum[(i-tree[id<<1].num+1000000)%5];
}
int main(){
char s[10];
int i,k,tem,pos,n;
while(scanf("%d",&n)!=EOF){
k=0;
for(i=1;i<=n;i++){
scanf("%s",s);
if(s[0]=='a'){
sel[i]=1;
scanf("%d",&tem);
pn[i]=px[k++]=tem;
}
else if(s[0]=='d'){
sel[i]=2;
scanf("%d",&tem);
pn[i]=tem;
}
else
sel[i]=3;
}
sort(px,px+k);
int nn=unique(px,px+k)-px;
if(nn!=0)
build(1,nn,1);
for(i=1;i<=n;i++){
if(sel[i]==1){
pos=lower_bound(px,px+nn,pn[i])-px+1;
insert(pos,pn[i],1,1);
}
else if(sel[i]==2){
pos=lower_bound(px,px+nn,pn[i])-px+1;
insert(pos,-pn[i],-1,1);
}
else{
if(nn==0)
printf("0\n");
else
printf("%I64d\n",tree[1].sum[3]);
}
}
}
}