思路:一開始想水一下,結果超時。先對所有輸入的數字離散化,線段樹維護區間上點的個數和5個sum值,區間合併的時候要注意:左兒子節點和父親節點的關係很容易,右兒子合併的時候與左兒子中的點個數有關。
代碼如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<stdio.h>
#include<math.h>
#define LL __int64
#define N 100005
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
char cins[N][10];
int cinx[N];
int a[2*N];
struct node
{
int l,r,cnt;
LL sum[5];
}tree[2*N*4];
void build(int o,int l,int r)
{
tree[o].l = l;
tree[o].r = r;
tree[o].cnt = 0;
for(int i = 0; i < 5; i++) tree[o].sum[i] = 0;
if(l == r) return ;
int m = (l + r)/2;
build(2*o,l,m);
build(2*o+1,m+1,r);
}
void pushup(int o)
{
tree[o].cnt = tree[2*o].cnt + tree[2*o+1].cnt;
for(int i = 0; i < 5; i++)
tree[o].sum[i] = tree[2*o].sum[i];
for(int i = 0; i < 5; i++)
tree[o].sum[(i+tree[2*o].cnt) % 5] += tree[2*o+1].sum[i];
}
void update(int o,int pos,int v)
{
if(tree[o].l == tree[o].r)
{
tree[o].sum[1] = v;
if(v == 0) tree[o].cnt--;
else tree[o].cnt++;
return ;
}
int m = (tree[o].l + tree[o].r)/2;
if(pos <= m) update(2*o,pos,v);
else update(2*o+1,pos,v);
pushup(o);
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int n;
while(scanf("%d",&n) != EOF)
{
int i,tot = 0;
for(i = 0; i < n; i++)
{
scanf("%s",cins[i]);
if(cins[i][0] != 's')
{
scanf("%d",&cinx[i]);
a[tot++] = cinx[i];
}
}
sort(a,a+tot);
tot = unique(a,a+tot) - a;
build(1,1,tot);
for(int i = 0; i < n; i++)
{
if(cins[i][0] == 's')
printf("%I64d\n",tree[1].sum[3]);
else
{
int pos = lower_bound(a,a+tot,cinx[i]) - a + 1;
//cout<<pos<<" "<<cinx[i]<<endl;
if(cins[i][0] == 'a')
update(1,pos,cinx[i]);
else update(1,pos,0);
}
}
}
return 0;
}