Week5 HomeWork B TT's MagicCat 前缀和与差分

1 篇文章 0 订阅
1 篇文章 0 订阅

题目描述

Thanks to everyone’s help last week, TT finally got a cute cat. But what TT didn’t expect is that this is a magic cat.

One day, the magic cat decided to investigate TT’s ability by giving a problem to him. That is select n cities from the world map, and a[i] represents the asset value owned by the i -th city.

Then the magic cat will perform several operations. Each turn is to choose the city in the interval [l,r] and increase their asset value by c. And finally, it is required to give the asset value of each city after q operations.

Could you help TT find the answer?

上星期多亏了大家的帮助,TT终于有了一只可爱的猫。但没想到的是这是一只神奇的猫。

有一天,这只神奇的猫决定给TT一个问题来研究TT的能力。即选择了n个世界地图上的城市,a[i]代表第i个城市拥有的资产价值。 然后魔术猫将执行几个操作。每个回合都要选择区间内的城市[lr]并将其资产价值增加c。最后,需要给出每个城市在q之后的资产价值
你能帮TT找到答案吗?

Input

The first line contains two integers n,q(1≤n,q≤2⋅105)— the number of cities and operations.
The second line contains elements of the sequence a
: integer numbers a1,a2,…,a*n*(−106ai≤106)
Then q lines follow, each line represents an operation. The i-th line contains three integers l,r and c(1≤
l
rn,−105c≤105) for the i-th operation.

第一行包含两个整数nq(1≤nq≤2⋅105)-城市和业务的数量。第二行包含序列a的元素 :整数a1a2,…,an(-106≤ai≤106
接下来是q行,每一行代表一个操作。第i行包含三个整数lrc(1≤lrn,-105c≤105),用于第i行操作。

Output

Print n integers a1,a2,…,an one per line, and ai should be equal to the final asset value of the i-th city.

打印n个整数a1a2,…,*an*每行一个,ai应等于第i个城市的最终资产价值。

Sample Input 1

4 2
-3 6 8 4
4 4 -2
3 3 1

Sample Output 1

-3 6 9 2

Sample Input 2

2 1
5 -2
1 2 4

Sample Output 2

9 2

Sample Input 3

1 2
0
1 1 -8
1 1 -6

Sample Output 3

-14

算法/思路分析

简化题意为:已知一个长度为n的数组a[n],q次操作,每次操作a[l]…a[r]+=c,问q次操作后数组中每个元素的值

首先,直接按照题意暴力,a数组逐个元素加c,复杂度为O(qn)~O(n^2),而n范围为2e5,会TLE。

考虑优化,注意到每次操作都是区间内的连续元素加同一个值,由此,可以利用差分数组将区间修改转化为单点修改。即构造差分数组b[n-1]:b[1]=a[1],b[i] = a[i] - a[i-1] i ∈[2,n]。则a[l]…a[r] += c 相当于b[l] += c, b[r + 1] -= c。最后,只需求b数组的前缀和即可得a数组的每个元素值a[k] = ∑i=1kb[i]。复杂度为O(n + q)~O(n)

代码

#include <cstdio>
#include <iostream>
#include <stack>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 2e5+10;
#define ll long long
ll n,q,a[maxn],b[maxn];


int main()
{
	scanf("%d%d",&n,&q);
	for(int i = 1; i <= n; i++) scanf("%lld",&a[i]);
	
	//构建差分数组 
	b[1] = a[1];
	for(int i = 2; i <= n; i++) b[i] = a[i] - a[i-1];
	//将a数组的各点增加转化为b数组两个数增加 
	for(int i = 0; i < q; i++)
	{
		ll l,r,c;
		scanf("%lld%lld%lld",&l,&r,&c);
		b[l] += c; b[r+1] -= c;
	}
	
	//b数组前缀和即a数组元素值 
	a[1] = b[1];
	for(int i = 2; i <= n; i++) a[i] = a[i-1] + b[i];
	
	for(int i = 1; i <= n; i++) 
	{
		if(i > 1) printf(" ");
		printf("%lld",a[i]);
	} 
	printf("\n"); 
	return 0;
} 
/*
4 2
-3 6 8 4
4 4 -2
3 3 1

2 1
5 -2
1 2 4

1 2
0
1 1 -8
1 1 -6
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值