ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

线段树求和

2022-01-21 23:00:47  阅读:154  来源: 互联网

标签:Aa ... 结点 求和 线段 given Query line


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));
		}

	}
}

标签:Aa,...,结点,求和,线段,given,Query,line
来源: https://www.cnblogs.com/tzp-empty-hya/p/15832086.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有