CF_85D

    这个题目可以用sum[cur][i]表示第cur个节点所辖区间的下标模5为i的整数之和,这样只要再加一个表示节点所辖区间的整数数目的标记num[cur],每次就可以方便的计算出sum[cur][i]的值了

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXD 100010
struct Question
{
    char b[5];
    int x;
}question[MAXD];
int N, num[4 * MAXD], tx[MAXD], X;
long long int sum[4 * MAXD][5];
int cmp(const void *_p, const void *_q)
{
    int *p = (int *)_p, *q = (int *)_q;
    return *p < *q ? -1 : 1;
}
void build(int cur, int x, int y)
{
    int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
    memset(sum[cur], 0, sizeof(sum[cur]));
    num[cur] = 0;
    if(x == y)
        return ;
    build(ls, x, mid);
    build(rs, mid + 1, y);
}
void init()
{
    int i, j, k;
    for(i = k = 0; i < N; i ++)
    {
        scanf("%s", question[i].b);
        if(question[i].b[0] == 'a' || question[i].b[0] == 'd')
        {
            scanf("%d", &question[i].x);
            tx[k ++] = question[i].x;
        }
    }
    qsort(tx, k, sizeof(tx[0]), cmp);
    X = 0;
    for(i = 0; i < k; i ++)
        if(i == 0 || tx[i] != tx[i - 1])
            tx[X ++] = tx[i];
    if(X)
        build(1, 0, X - 1);
}
int BS(int x)
{
    int mid, min = 0, max = X;
    for(;;)
    {
        mid = (min + max) >> 1;
        if(mid == min)
            break;
        if(tx[mid] <= x)
            min = mid;
        else
            max = mid;
    }
    return mid;
}
void update(int cur)
{
    int i, ls = cur << 1, rs = (cur << 1) | 1;
    num[cur] = num[ls] + num[rs];
    for(i = 0; i < 5; i ++)
        sum[cur][i] = sum[ls][i] + sum[rs][(i + 5 - num[ls] % 5) % 5];
}
void refresh(int cur, int x, int y, int k, int c)
{
    int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
    if(x == y)
    {
        if(c)
            num[cur] = 1, sum[cur][0] = tx[k];
        else
            num[cur] = 0, sum[cur][0] = 0;
        return ;
    }
    if(k <= mid)
        refresh(ls, x, mid, k, c);
    else
        refresh(rs, mid + 1, y, k, c);
    update(cur);
}
void ADD(int x)
{
    int k = BS(x);
    refresh(1, 0, X - 1, k, 1);
}
void Del(int x)
{
    int k = BS(x);
    refresh(1, 0, X - 1, k, 0);
}
void solve()
{
    int i, j, k;
    for(i = 0; i < N; i ++)
    {
        if(question[i].b[0] == 'a')
            ADD(question[i].x);
        else if(question[i].b[0] == 'd')
            Del(question[i].x);
        else
            printf("%I64d\n", sum[1][2]);
    }
}
int main()
{
    while(scanf("%d", &N) == 1)
    {
        init();
        solve();
    }
    return 0;
}
posted on 2012-04-16 22:49  Staginner  阅读(508)  评论(0编辑  收藏  举报