henu TonyStark with Sequence(差分)

题目链接

题目描述

输入一个数 t ,表示有 t 组测试数据

每组给定一个度为 n (1 <= n <= 10000000) 的数列,共有 m (1 <= m <= 10000000) 次操作,每次操作给定一个区间 [ l , r ] (1 <= l <= r <= n) ,和一个数 v (-100 <= v <= 100)  ,是该区间内所有的数加上 v ,对于每组测试数据,输出 m 次操作后数列中的值

Simple input && output

1
5 3
1 2 3 4 5
1 3 1
2 3 -1
1 1 -1
1 2 3 4 5

本题是对区间进行操作,一眼就能看出可以用线段树求解,但是线段树的代码较为长,又结合本题只有最后一次求解,中间都是更新过程,可以使用差分区间去求解,注意差分数组的初始化问题,初始值应该是当前的值和前一个位置的值的差,对于第一个值,它与前一个数的值差初始化为0

#include 
#include 
#include 
#include 
#include 
using namespace std;
int t, n, m, v, ll, rr, sum;
const int maxn = 1e7+10;
int a[maxn], s[maxn];
namespace ans{
	void MAIN(){
		scanf("%d", &t);
		while (t--){
			scanf("%d %d", &n, &m);
			memset(s, 0, sizeof s);
			for (int i = 1; i <= n; i++)scanf("%d", s + i);
			s[0] = s[1];
			memset(a, 0, sizeof a);
			for (int i = 1; i <= n; i++){
				a[i] = s[i] - s[i - 1];
			}
			while (m--){
				scanf("%d %d %d", &ll, &rr, &v);
				a[ll] += v;
				a[rr + 1] -= v;
			}
			s[1] = a[1] + s[0];
			printf("%d", s[1]);
			for (int i = 2; i <= n; i++){
				s[i] = s[i - 1] + a[i];
				printf(" %d", s[i]);
			}
			printf("\n");
		}
		
	}
}
int main()
{
	ans::MAIN();
	return 0;
}

 

你可能感兴趣的:(常用算法)