hdu4288(線段樹維護多個sum)

題意:給n個有序的數字,三個操作:1、刪除數字x;2、增加數字x;3、求i%5=3的數字之和(i爲數字的下標)

思路:一開始想水一下,結果超時。先對所有輸入的數字離散化,線段樹維護區間上點的個數和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;
}


發佈了231 篇原創文章 · 獲贊 15 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章