农夫约翰的奶牛们非常爱吃甜食,尤其爱吃拐杖糖。
约翰一共有 N 头奶牛,编号 1∼N,其中第 ii头奶牛的初始高度为 ai。
约翰给奶牛们准备了 M 根拐杖糖,编号 1∼M,其中第 i 根的高度为 bi。
约翰会按照糖果的编号顺序,每次拿出一根糖果喂给奶牛们,直到所有糖果都被喂完为止。
每当拿出一根糖果后,约翰会将其上端固定悬挂,下端自由下垂至刚好接触地面。
然后,奶牛们按照编号顺序,依次走到糖果面前,将糖果自下而上的啃食至自己的高度(因为更高的地方吃不到了)。
由于糖果上端是固定的,所以即使奶牛吃掉糖果的下端部分,糖果也会悬挂在最初设置的位置,不会下降至地面。
当轮到一个奶牛时,如果糖果剩余部分的底部高度已经超过了该奶牛的高度,那么它将什么都吃不到。
在所有奶牛都轮过一次后,不论这根糖果是否被吃完,该糖果都会被约翰扔掉,并换上下一根糖果,继续下一轮次的吃糖(仍然从编号为 11 的奶牛开始)。
另外,每轮过后,糖果都有可能令奶牛们的身高有所增长,具体为一头奶牛在本轮次吃掉了多少长度的糖果,其身高就会增高多少长度。
请你计算,当所有糖果都喂食完毕后,每头奶牛的最终高度。
输入格式
第一行包含两个整数 N,M。
第二行包含 NN 个整数 a1,a2,…,aN。
第三行包含 MM 个整数 b1,b2,…,bM。
输出格式
共 NN 行,其中第 ii 行输出第 ii 头奶牛的最终高度。
数据范围
1≤N,M≤2×105,
1≤ai,bi≤109
输入样例:
3 2
3 2 5
6 1
输出样例:
7
2
7
样例解释
第 1 根糖果的高度为 6:
- 第 1头牛吃掉高度不超过 3 的部分,糖果剩余部分高度 [3,6]。
- 第 2 头牛不够高,吃不到任何糖果。
- 第 3头牛吃掉高度不超过 5 的部分,糖果剩余部分高度 [5,6]。
第 1 根糖果喂完,奶牛们的高度变为 [3+3,2+0,5+2]=[6,2,7]。
第 2 根糖果的高度为 1,会被第 1头奶牛全部吃掉。
所以,最终奶牛们的高度变为 [7,2,7]。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL; // 定义 long long 类型为 LL,方便使用
const int N = 200010; // 定义数组的最大大小
int n, m; // n 表示数组 a 的长度,m 表示数组 b 的长度
LL a[N]; // 存储数组 a 的元素
int b[N]; // 存储数组 b 的元素
int main()
{
scanf("%d%d", &n, &m); // 输入数组 a 的长度 n 和数组 b 的长度 m
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]); // 输入数组 a 的元素
for (int i = 1; i <= m; i++) scanf("%d", &b[i]); // 输入数组 b 的元素
// 遍历数组 b 中的每个元素,模拟“吃”的过程
for (int i = 1; i <= m; i++)
{
int t = 0; // 当前已经“吃”了多少
for (int j = 1; j <= n; j++) // 遍历数组 a 的每个元素
{
if (a[j] <= t) continue; // 如果当前元素 a[j] 已经被完全“吃掉”,跳过
int eat = min(a[j], (LL)b[i]) - t; // 计算当前可以“吃”的数量
a[j] += eat; // 更新数组 a[j] 的值(增加 eat)
t += eat; // 更新已“吃”的总数
if (t == b[i]) break; // 如果已经“吃”够了 b[i],结束当前循环
}
}
// 输出最终数组 a 的每个元素
for (int i = 1; i <= n; i++) printf("%lld\n", a[i]);
return 0; // 程序结束
}