线段树求和

P1003: A Simple Problem with Integers
题目描述
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.

输入
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.
输出
You need to answer all Q commands in order. One answer in a line.

样例输入
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
样例输出
4
55
9
15

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>
//理解结点标号,结点的左右结点标号是当前结点的2倍和2倍加1,一个结点的区间范围由结点的l和r唯一确定
//这两个概念不应该混为一谈
#define lson (x<<1)
#define rson ((x<<1)|1)
const int N = 100005;
typedef long long ll;
typedef struct node
{
	int l, r;
	ll val, lazy;
}node;

node tree[N * 4];
ll a[N];
int n;

void PushUp(int x)
{
	tree[x].val = tree[lson].val + tree[rson].val;
}

void PushDown(int x)
{
	if (tree[x].lazy) {
		tree[lson].lazy += tree[x].lazy;
		tree[rson].lazy += tree[x].lazy;
		tree[lson].val += tree[x].lazy * (tree[lson].r - tree[lson].l + 1);
		tree[rson].val += tree[x].lazy * (tree[rson].r - tree[rson].l + 1);
		tree[x].lazy = 0;
	}
}

void Build(int x, int l, int r)//l和r分别是编号为x的结点左区间和右区间
{
	tree[x].l = l, tree[x].r = r, tree[x].lazy = 0;
	if (l == r) {
		tree[x].val = a[l]; return;
	}
	int mid = (l + r) / 2;
	Build(lson, l, mid);
	Build(rson, mid + 1, r);
	PushUp(x);

}


void Update(int x, int l, int r, int add)
{
	if (tree[x].l >= l && tree[x].r <= r) {
		tree[x].lazy += add;
		tree[x].val += (tree[x].r - tree[x].l + 1) * add;
		return;
	}
	PushDown(x);
	int mid = (tree[x].l + tree[x].r) / 2;
	if (l <= mid)Update(lson, l, r, add);
	if (mid < r)Update(rson, l, r, add);
	PushUp(x);
	return;
}




ll Query(int x, int l, int r)
{
	if (tree[x].l >= l && tree[x].r <= r)return tree[x].val;
	PushDown(x);
	int mid = (tree[x].l + tree[x].r) / 2;
	if (r <= mid)return Query(lson, l, r);
	else if (l > mid)return Query(rson, l, r);
	else return Query(lson, l, r) + Query(rson, l, r);
}



int main()
{
	int n, m;
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++)scanf("%lld", &a[i]);
	Build(1, 1, n);
	for (int i = 0; i < m; i++) {
		char temp;
		int x, y;
		ll val;
		scanf("\n%c %d %d", &temp, &x, &y);//读取一个换行
		if (temp == 'C')
		{
			scanf("%lld", &val);
			Update(1, x, y, val);
		}
		else {
			printf("%lld\n", Query(1, x, y));
		}

	}
}
上一篇:用paddleocr打造一款“盗幕笔记”


下一篇:文本超出转省略号