HDU 4288 Coder 離線線段樹部分更新

來源:互聯網
上載者:User

題意:下標模5等於3的數的和。

題解:

可以這樣,線段樹的每個節點存一個數組 sum[5],表示當前節點覆蓋的區間中,從左到有編號,模 5 為 0,1,2,3,4的所有數的和

每個節點再儲存一個當前節點所包含的區間中有多少個數的資訊:cnt。那麼:

        添加的時候就是在相應的位置把整數加進去,並把 cnt+1

        刪除的時候就是在相應的位置賦值為 0,並把 cnt-1

關於 pushUp 的問題,我們可以這樣考慮:

        父親的 cnt 肯定是兩個兒子的 cnt 的和

        父親的 sum 肯定賦初值為 左兒子 的 sum

        右兒子的 sum[i] 對應的是父親的 sum[(i+Lson.cnt)%5]


#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;#define MAXN 100009#define L(u) (u<<1)#define R(u) (u<<1|1)#define lint __int64struct NODE{    lint sum[5];    int l, r, cnt;} node[MAXN*3];int num[MAXN], val[MAXN], n; //num[0]記錄num的個數char oper[MAXN][5];void build(int u, int l, int r){    node[u].l = l;    node[u].r = r;    node[u].cnt = 0;    for(int i = 0; i < 5; i++)        node[u].sum[i] = 0;    if(node[u].l == node[u].r) return;    int mid = (l + r) >> 1;    build(L(u), l, mid);    build(R(u), mid + 1, r);}void pushUp(int u){    node[u].cnt = node[L(u)].cnt + node[R(u)].cnt;    int x = node[L(u)].cnt;    for(int i = 0; i < 5; i++)        node[u].sum[i] = node[L(u)].sum[i];    for(int i = 0; i < 5; i++)        node[u].sum[(x+i)%5] += node[R(u)].sum[i];}void update(int u, int index, int flag) //flag=1表示add,flag=-1表示del{    if(node[u].l == index && node[u].r == index)    {        node[u].cnt = 0;        for(int i = 0; i < 5; i++)            node[u].sum[i] = 0;        if(flag == 1)        {            node[u].sum[1] = num[index];            node[u].cnt = 1;        }        return;    }    int mid = (node[u].l + node[u].r) >> 1;    if(index <= mid) update(L(u), index, flag);    else update(R(u), index, flag);    pushUp(u);}int bfind(int l, int r, int key){    int mid;    while(l < r)    {        mid = (l + r) >> 1;        if(num[mid] == key) return mid;        else if(num[mid] < key) l = mid + 1;        else r = mid;    }    if(num[l] == key) return l;    return r;}int main(){    while(scanf("%d", &n) != EOF)    {        int i, j;        num[0] = 0;        for(i = 1; i <= n; i++)        {            scanf("%s", oper[i]);            if(oper[i][0] != 's')            {                scanf("%d", &val[i]);                num[++num[0]] = val[i];            }        }        sort(num+1, num+1+num[0]);        for(j = 1, i = 2; i <= num[0]; i++)            if(num[j] != num[i]) num[++j] = num[i];        num[0] = j;        build(1, 1, num[0]);        for(i = 1; i <= n; i++)        {            if(oper[i][0] == 's')                printf("%I64d\n", node[1].sum[3]);            else if(oper[i][0] == 'a')            {                int index = bfind(1, num[0], val[i]);                update(1, index, 1);            }            else            {                int index = bfind(1, num[0], val[i]);                update(1, index, -1);            }        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.