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

题目传送:A Simple Problem with Integers

思路:线段树,成段增减,区间求和,注意延迟标记需要累加,还有会爆int

AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <cctype>
#define LL long long
#define INF 0x7fffffff
using namespace std;

const int maxn = 100005;
LL sum[maxn << 2];
LL lazy[maxn << 2];

void pushdown(int rt, int m) {
	if(lazy[rt] != 0) {
		lazy[rt << 1] += lazy[rt];//延迟标记需累加,因为可能有别的区间在这里产生延迟标记
		lazy[rt << 1 | 1] += lazy[rt];
		sum[rt << 1] += (m - (m >> 1)) * lazy[rt];//区间加减更新
		sum[rt << 1 | 1] += (m >> 1) * lazy[rt];
		lazy[rt] = 0;//用完后记得置为0
	}
}

void build(int l, int r, int rt) {//建树
	lazy[rt] = 0;//延迟标记赋初值
	if(l == r) {
		scanf("%I64d", &sum[rt]);//题目中说会爆int,用64位输入输出
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}

void update(int L, int R, int c, int l, int r, int rt) {//更新
	if(L <= l && r <= R) {
		sum[rt] += (LL)(r - l + 1) * c;//虽然这里不会爆int,但是看到乘法要特别注意会不会爆int
		lazy[rt] += c;//累加延迟标记
		return;
	}
	pushdown(rt, r - l + 1);
	int mid = (l + r) >> 1;
	if(L <= mid) update(L, R, c, l, mid, rt << 1);
	if(R >= mid + 1) update(L, R, c, mid + 1, r, rt << 1 | 1);
	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}

LL query(int L, int R, int l, int r, int rt) {//查询
	if(L <= l && r <= R) {
		return sum[rt];
	}
	pushdown(rt, r - l + 1);
	int mid = (l + r) >> 1;
	LL ret = 0;
	if(L <= mid) ret += query(L, R, l, mid, rt << 1);
	if(R >= mid + 1) ret += query(L, R, mid + 1, r, rt << 1 | 1);
	return ret;
}

int main() {
	int n, q;
	while(scanf("%d %d", &n, &q) != EOF) {
		build(1, n, 1);
		char op[10];
		int a, b, c;
		for(int i = 0; i < q; i ++) {
			scanf("%s", op);
			if(op[0] == 'Q') {
				scanf("%d %d", &a, &b);
				printf("%I64d\n", query(a, b, 1, n, 1));
			}
			else {
				scanf("%d %d %d", &a, &b, &c);
				update(a, b, c, 1, n, 1);
			}
		}
	}
	return 0;
}
时间: 2024-12-24 07:32:51

POJ - 3468 - A Simple Problem with Integers (线段树 - 成段更新)的相关文章

POJ 3468 A Simple Problem with Integers 线段树成段更新

线段树功能 update:成段更新  query:区间求和 #include <iostream> #include <string> #include <cstdio> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; typedef long long ll; const int MAXN = 111111; ll sum[MAXN<&l

【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each

POJ3468_A Simple Problem with Integers(线段树/成段更新)

解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio> #define LL long long #define int_now int l,int r,int root using namespace std; LL sum[500000],lazy[500000]; void push_up(int root,int l,int r) { sum[ro

A Simple Problem with Integers 线段树 成段更新

Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3468 Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given

POJ 3468 A Simple Problem with Integers(线段树区间更新)

题目地址:POJ 3468 打了个篮球回来果然神经有点冲动..无脑的狂交了8次WA..居然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题.区间更新就是加一个lazy标记,延迟标记,只有向下查询的时候才将lazy标记向下更新.其他的均按线段树的来就行. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <math.h> #include <stac

poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解

A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of

POJ 3468 A Simple Problem with Integers (线段树区域更新)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 62431   Accepted: 19141 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

[POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]

A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of

POJ 3468 A Simple Problem with Integers //线段树的成段更新

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 59046   Accepted: 17974 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

poj 3468 A Simple Problem with Integers 线段树加延迟标记

A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of