描述
在一个桌子上摆放了n个杯子,每个杯子中有一定量的水。小A同学负责向杯子中倒水,他总共倒了k次,每次会向从第L个杯子到第R个杯子中添加P毫升的水(注意:水只可能增加,不可能减少)。
请问小A同学倒了k次水之后,n个杯子每个杯子有多少毫升的水。
输入描述
第一行包含两个整数n和k。
第二行包含n个整数,表示一开始每个杯子中水的毫升数。
接下来k行,每行包含三个整数L,R,P,表示一次操作。
输出描述
共一行,包含n个整数,表示最终n个杯子每个杯子有多少毫升的水。
用例输入 1
8 3 1 2 10 8 1 5 1 1 7 8 12 1 8 4 2 3 12
用例输出 1
5 18 26 12 5 9 17 17
提示
【数据范围】
1≤n,k≤100000,
1≤L≤R≤n,
0≤P≤1000,
0≤杯子中水的初始量≤1000
来源
前缀和差分
解析:
-
初始化:首先定义了两个数组
a
和b
,其中a
数组用于存储每个杯子最初的水量,b
数组用于记录每次倒水后的水量变化。b[i]
的值表示从第1个杯子到第i个杯子之间总共增加的水量。 -
输入:从输入中读取杯子的数量
n
和倒水的次数m
,然后读取每个杯子最初的水量到a
数组中。 -
计算初始水量变化:通过
a
数组计算b
数组,b[i]
存储的是第i个杯子相对于第i-1个杯子多出的水量。这里假设第0个杯子的水量为0,因此b[1]
即为第一个杯子的水量。 -
倒水操作:对于每次倒水操作,读取倒水的范围
l
和r
以及水量p
。在b
数组的l
位置加上p
,表示从第l
个杯子开始增加水量;在r+1
位置减去p
,表示在第r
个杯子之后的水量要减去p
,确保水量只在l
到r
之间增加。 -
计算最终水量:遍历
b
数组,累加水量变化,得到每个杯子最终的水量。这里通过累加操作将水量变化从b[1]
到b[n]
依次累加起来,最终b[i]
存储的就是第i个杯子最终的水量。 -
输出:输出每个杯子最终的水量。
代码:
#include<iostream>
using namespace std; // 定义常量N,表示数组的最大长度
const int N = 100007; // 定义全局变量
int n, m, l, r, p; // n表示杯子数量,m表示倒水的次数,l和r表示倒水的范围,p表示每次倒水的量
int a[N], b[N]; // a数组存储每个杯子最初的水量,b数组用于记录每次倒水后的水量变化 int main() { // 输入杯子数量n和倒水次数m cin >> n >> m; // 初始化a数组,存储每个杯子最初的水量 for(int i = 1; i <= n; i++) { cin >> a[i]; // 计算b数组,b[i]表示第i个杯子相对于第i-1个杯子多出的水量 // 注意:a[0]未定义,这里假设a[0]为0,即第0个杯子水量为0 b[i] = a[i] - a[i - 1]; } // 执行m次倒水操作 for(int i = 1; i <= m; i++) { // 输入每次倒水的范围l, r和水量p cin >> l >> r >> p; // 在b数组对应位置加上p,表示增加的水量 // l位置加上p,表示从第l个杯子开始增加水量 b[l] += p; // r+1位置减去p,表示在第r个杯子之后的水量要减去p // 这样可以确保在r位置结束增加水量 b[r + 1] -= p; } // 累加b数组,得到每个杯子最终的水量 // b[i]存储的是从第1个杯子到第i个杯子总共增加的水量 for(int i = 1; i <= n; i++) { // 计算每个杯子最终的水量,b[i]加上前一个杯子的水量b[i-1] b[i] = b[i] + b[i - 1]; // 输出每个杯子最终的水量 cout << b[i] << " "; } return 0;
}