POJ 3468 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 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 AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+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

一道线段树的模板题,把模板敲一遍就ok。

#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 100010;
typedef long long ll;
ll a[MAXN], ans[MAXN<<2], lazy[MAXN<<2];
//a[]原序列信息,ans[]模拟线段树维护区间和,lazy[]懒得标记

void PushUp(int rt) {
	ans[rt] = ans[rt<<1] + ans[rt<<1|1];
}

void Build(int l, int r, int rt) {
	if(l == r) {
		ans[rt] = a[l];
		return;
	}
	int mid = (l + r) >> 1;
	Build(l, mid, rt<<1);
	Build(mid + 1, r, rt<<1|1);
	PushUp(rt);
}

void PushDown(int rt, int ln, int rn) {
	if(lazy[rt]) {
		lazy[rt<<1] += lazy[rt];
		lazy[rt<<1|1] += lazy[rt];
		ans[rt<<1] += lazy[rt]*ln;
		ans[rt<<1|1] += lazy[rt]*rn;
		lazy[rt] = 0;
	}
}

void Add(int L, int c, int l, int r, int rt) {//点更新
	if(l == r) {
		ans[rt] += c;
		return;
	}
	int mid = (l + r) >> 1;
	if(L <= mid) {
		Add(L, c, l, mid, rt<<1);
	} else {
		Add(L, c, mid + 1, r, rt<<1|1);
	}
	PushUp(rt);
}

void Update(int L, int R, int C, int l, int r, int rt) {//区间更新
	if( L <= l && r <= R) {
		ans[rt] += C*(r - l + 1);
		lazy[rt] += C;
		return;
	}
	int mid = (l + r) >> 1;
	PushDown(rt, mid - l + 1, r - mid);
	if(L <= mid) {
		Update(L, R, C, l, mid, rt<<1);
	}
	if(R > mid) {
		Update(L, R, C, mid + 1, r, rt<<1|1);
	}
	PushUp(rt);
}

ll Query(int L, int R, int l, int r, int rt) {//区间查询
	if(L <= l && r <= R) {
		return ans[rt];
	}
	int mid = (l + r) >> 1;
	PushDown(rt, mid - l + 1, r - mid);
	ll ANS = 0;
	if(L <= mid) {
		ANS += Query(L, R, l, mid, rt<<1);
	} 
	if(R > mid) {
		ANS += Query(L, R, mid + 1, r, rt<<1|1);
	}
	return ANS;
}
int main() {
	int n, m, x, y, c;
	char ch;
	while(cin>>n>>m) {
		memset(a, 0, sizeof(a));
		for(int i = 1; i <= n; i++) {
			cin>>a[i];
		}
		Build(1, n, 1);
		while(m--) {
			getchar();
			cin>>ch;
			if(ch == 'Q') {
				cin>>x>>y;
				cout<<Query(x, y, 1, n, 1)<<endl;
			} else {
				cin>>x>>y>>c;
				Update(x, y, c, 1, n, 1);
			}
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/adusts/article/details/81232961