您的位置:首页 > 其它

POJ - 3468 A Simple Problem with Integers(线段树)

2015-10-20 22:51 316 查看
题目大意:中文题

解题思路:线段树区间修改裸题

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 100010 << 2;

LL setv
, val
, sum
;
int n, q;

void PushUp(int u) {
sum[u] = sum[u << 1] + sum[u << 1 | 1];
}

void PushDown(int u, int k) {
if (setv[u] != 0) {
int l = u << 1;
int r = u << 1 | 1;
setv[l] += setv[u];
setv[r] += setv[u];
sum[l] += (k - (k >> 1)) * setv[u];
sum[r] += (k >> 1) * setv[u];
setv[u] = 0;
}
}

void build(int u, int l, int r) {
setv[u] = 0;
if (l == r) {
sum[u] = val[l];
return ;
}
int mid = (l + r) >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
PushUp(u);
}

void init() {
for (int i = 1; i <= n; i++)
scanf("%lld", &val[i]);
build(1, 1, n);
}

void modify(int u, int l, int r, int L, int R, LL c) {
if (L <= l && r <= R) {
setv[u] += c;
sum[u] += (r - l + 1) * c;
return ;
}
PushDown(u, r - l + 1);
int mid = (l + r) >> 1;
if (L <= mid) modify(u << 1, l, mid, L, R, c);
if (R > mid) modify(u << 1 | 1, mid + 1, r, L, R, c);
PushUp(u);
}

LL query(int u, int l, int r, int L, int R) {
if (L <= l && r <= R)  return sum[u];

PushDown(u, r - l + 1);
int mid = (l + r) >> 1;
LL ans = 0;
if (L <= mid) ans += query(u << 1, l, mid, L, R);
if (R > mid) ans += query(u << 1 | 1, mid + 1, r, L ,R);
return ans;
}

void solve() {
char op[4];
int a, b;
LL c;
while (q--) {
scanf("%s", op);
if (op[0] == 'Q') {
scanf("%d%d", &a, &b);
printf("%lld\n", query(1, 1, n, a, b));
}
else {
scanf("%d%d%lld", &a, &b, &c);
modify(1, 1, n, a, b, c);
}
}
}

int main() {
while (scanf("%d%d", &n, &q) != EOF) {
init();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: