您的位置:首页 > 其它

POJ 3468 – A Simple Problem with Integers

2012-08-02 22:57 323 查看


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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: