5
solution:
首先我们将所有的数字读入然后通过去重得到要操作的数字,然后对于每一个节点维护sum[5]和cnt分别表示5个位置的和以及个数,那么对于一个父亲节点,左孩子节点对应的5个位置的和和父亲节点一样,但对于有孩子来说不同,设左孩子含有的有效节点个数为cnt,那么右孩子中第x个位置%5在父亲中是第i个 那么有(cnt+x)%5==i,解得x=(i-cnt)%5
#include
#include
using namespace std;
#define ls t<<1
#define rs (t<<1)|1
const int maxn = 1e5 + 200;
#define ll long long
ll a[maxn];
struct node
{
char op[5];
ll x;
}query[maxn];
struct Node
{
ll sum[5];
int l, r, cnt;
}tree[maxn*4];
void build(int l, int r, int t)
{
tree[t].l = l;
tree[t].r = r;
tree[t].cnt = 0;
for (int i = 0; i < 5; i++)
tree[t].sum[i] = 0;
if (l == r)return;
int mid = (l + r) / 2;
build(l, mid, ls);
build(mid + 1,r,rs);
}
void update(int pos, long long val, int cnt,int t)
{
tree[t].cnt += cnt;
if (tree[t].l == tree[t].r)
{
tree[t].sum[0] += val;
return;
}
int mid = (tree[t].l + tree[t].r) / 2;
if (pos <= mid)update(pos, val, cnt, ls);
else update(pos, val, cnt, rs);
for (int i = 0; i < 5; i++)
tree[t].sum[i] = tree[ls].sum[i] + tree[rs].sum[((i-tree[ls].cnt+5)%5+5)% 5];
}
int main()
{
int n,pos;
while (~scanf("%d", &n))
{
int cnt = 1;
for (int i = 0; i < n; i++)
{
scanf("%s", query[i].op);
if (query[i].op[0] != 's')
{
scanf("%I64d", &query[i].x);
a[cnt++] = query[i].x;
}
}
sort(a+1, a + cnt);
cnt = unique(a + 1, a + cnt) - a - 1;
build(1, cnt, 1);
for (int i = 0; i < n; i++)
{
if (query[i].op[0] == 's')
printf("%I64d\n", tree[1].sum[2]);
else {
pos = lower_bound(a + 1, a + cnt, query[i].x) - a;
if (query[i].op[0] == 'a')update(pos, query[i].x, 1,1);
else update(pos, -query[i].x,-1, 1);
}
}
}
return 0;
}