POJ 3468 – A Simple Problem with Integers

来源:互联网 发布:盛科网络上市没 编辑:程序博客网 时间:2024/06/05 11:04

Advanced Data Structures :: Segment Tree


Description

输入一个数列 {A1, A2, … , An} ,对其进行一系列操作:

  • Q a b 表示,询问一段连续的数列(从Aa到Ab)之和,并且输出。
  • C a b c 表示,修改一段连续的数列(从Aa到Ab),让他们自增c。


Type

Advanced Data Structures :: Segment Tree

Advanced Data Structures :: Binary Indexed Tree


Analysis

经典的线段树或数状数组的题目,要求能够成段更新。

利用线段树做延迟标记的时候,记得应该让延迟标记的值自增,而不是直接赋值。

且这题结果可能大于int,应使用long long


Solution

1. Segment Tree

// POJ 3468// A Simple Problem with Integers// by A Code Rabbit#include <cstdio>#define LSon(x) ((x) << 1)#define RSon(x) ((x) << 1 | 1)const int MAXN = 100002;const int ROOT = 1;struct Seg {    long long w;    int flag;};struct SegTree {    Seg node[MAXN << 2];    void Update(int pos) { node[pos].w = node[LSon(pos)].w + node[RSon(pos)].w; }    void Build(int l, int r, int pos) {        node[pos].flag = 0;        if (l == r) {            scanf("%lld", &node[pos].w);            return;        }        int m = l + r >> 1;        Build(l, m, LSon(pos));        Build(m + 1, r, RSon(pos));        Update(pos);    }    void Push(int l, int r, int pos) {        Seg& father = node[pos];        Seg& lson = node[LSon(pos)];        Seg& rson = node[RSon(pos)];        int len = r + 1 - l;        if (father.flag) {            lson.flag += father.flag;            rson.flag += father.flag;            // Pay attention to changing int into long long.            lson.w += (long long)father.flag * (len - (len >> 1));            rson.w += (long long)father.flag * (len >> 1);            father.flag = 0;        }    }    void Modify(int l, int r, int pos, int x, int y, int z) {        if (x <= l && r <= y) {            int len = r + 1 - l;            // Pay attention to changing int into long long.            node[pos].w += (long long)z * len;            node[pos].flag += z;            return;        }        Push(l, r, pos);        int m = l + r >> 1;        if (x <= m) Modify(l, m, LSon(pos), x, y, z);        if (y > m) Modify(m + 1, r, RSon(pos), x, y, z);        Update(pos);    }    long long Query(int l, int r, int pos, int x, int y) {        if (x <= l && r <= y) return node[pos].w;        Push(l, r, pos);        int m = l + r >> 1;        long long res = 0;        if (x <= m) res += Query(l, m, LSon(pos), x, y);        if (y > m) res += Query(m + 1, r, RSon(pos), x, y);        return res;    }};int n, q;char ch;int a, b, c;SegTree tree;int main() {    while (scanf("%d%d", &n, &q) != EOF) {        tree.Build(1, n, ROOT);        while (q--) {            getchar();            scanf("%c", &ch);            if (ch == 'Q') {                scanf("%d%d", &a, &b);                printf("%lld\n", tree.Query(1, n, ROOT, a, b));            } else            if (ch == 'C') {                scanf("%d%d%d", &a, &b, &c);                tree.Modify(1, n, ROOT, a, b, c);            }        }    }    return 0;}

2. Binary Indexed Tree
// POJ 3468// A Simple Problem with Integers// by A Code Rabbit#include <cstdio>#include <cstring>const int MAXN = 100002;struct Bit {    long long c[MAXN];    int n;    void Init(int x) { memset(c, 0, sizeof(c)); n = x; }    void Add(int x, long long y) {        while (x <= n) { c[x] += y; x += x & -x; }    }    long long Sum(int x) {        long long res = 0;        while (x > 0) { res += c[x]; x -= x & -x; }        return res;    }};struct NewBit {    Bit b1, b2;    void Init(int x) { b1.Init(x); b2.Init(x); }    void Add(int x, int y, long long z) {        b1.Add(x, z);        b1.Add(y + 1, -z);        b2.Add(x, z * x);        b2.Add(y + 1, -z * (y + 1));    }    long long Sum(int x) { return (x + 1) * b1.Sum(x) - b2.Sum(x); }};int n, q;int a, b, c;char ch;NewBit bit;int main() {    scanf("%d%d", &n, &q);    bit.Init(n);    for(int i = 0; i < n; i++) {        scanf("%d", &a);        bit.Add(i + 1, i + 1, a);    }    while (q--) {        getchar();        scanf("%c", &ch);        if(ch == 'Q'){            scanf("%d%d", &a, &b);            printf("%lld\n", bit.Sum(b) - bit.Sum(a - 1));        } else {            scanf("%d%d%d", &a, &b, &c);            bit.Add(a, b, c);        }    }    return 0;}


原创粉丝点击