ICode9

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

线段树 POJ - 3468 A Simple Problem with Integers

2021-10-05 14:34:30  阅读:195  来源: 互联网

标签:Integers Simple sum mid long 3468 int add include


地址 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;
}

我的视频题解空间

标签:Integers,Simple,sum,mid,long,3468,int,add,include
来源: https://www.cnblogs.com/itdef/p/15368558.html

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

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

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

ICode9版权所有