线段树 POJ - 3468 A Simple Problem with Integers

地址 https://vjudge.ppsucxtt.cn/problem/POJ-3468

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 numbers in a given interval.

Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

Output
You need to answer all Q commands in order. One answer in a line.

Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15
Hint
The sums may exceed the range of 32-bit integers.

解答 题目的大意是
给出一个整数数列, A[1] ~~ A[N]
有以下两个操作
1 Q a b 查询数组A[]中 索引a到索引b所有的数的和
2 C a b c 对数组A[]中 索引a到索引b的所有的数 全部加上一个数c
对于每个操作1的查询 打印出结果 结果占一行

对于线段树方案,这是一个区间更新 区间查询的方案。
对于区间更新,不能高效的实现对一段区域添加一个值,因为需要对这个区间相关的所有节点均进行更新
todo

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <assert.h>
#include <algorithm>

using namespace std;

const int N = 100010;

struct Node {
	int l; int r;
	long long sum;
	long long add;
}t[4 * N];
int arr[N];

int n, m;

void build(int p, int l, int r) {
	t[p].l = l; t[p].r = r;
	if (l == r) { t[p].sum = arr[l]; return; }

	int mid = (l + r) >> 1;
	build(p * 2, l, mid);
	build(p * 2 + 1, mid + 1, r);
	t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
}

void pushDown(int p) {
	if (t[p].add) {
		t[p * 2].sum += t[p].add*(t[p*2].r-t[p*2].l+1);
		t[p * 2+1].sum += t[p].add*(t[p * 2+1].r - t[p * 2+1].l + 1);
		t[p * 2].add += t[p].add;
		t[p * 2+1].add += t[p].add;
		t[p].add = 0;
	}
}


void update(int p, int l, int r, int d) {
	if (l <= t[p].l && r >= t[p].r) {
		t[p].sum += (long long)d* (t[p].r - t[p].l + 1);
		t[p].add += d;
		return;
	}
	pushDown(p);
	int mid = (t[p].l + t[p].r) >> 1;
	if (l <= mid) update(p * 2, l, r, d);
	if (r > mid) update(p * 2 + 1, l, r, d);
	t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
}


long long query(int p, int l, int r) {
	if (l <= t[p].l && r >= t[p].r) return t[p].sum;
	pushDown(p);
	int mid = (t[p].l + t[p].r) >> 1;
	long long val = 0;
	if (l <= mid) val += query(p * 2, l, r);
	if (r > mid) val += query(p * 2 + 1, l, r);
	return val;
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		scanf("%d",&arr[i]);
	}
	
	build(1, 1, n);

	for (int i = 0; i < m; i++) {
		char Q[2];
		int j, k, l;
		scanf("%s", &Q);

		if (Q[0] == 'Q') {
			scanf("%d%d",&j,&k);
			printf("%lld\n", query(1,j,k));
		}
		else if(Q[0]=='C') {
			scanf("%d%d%d", &j, &k,&l);
			update(1,j,k,l);
		}
		else {
			assert(0);
		}
	}

	return 0;
}

我的视频题解空间

上一篇:js判断当前浏览器是否是源生app的webview


下一篇:TypeError: list indices must be integers or slices, not tuple