[差分]Helping the Nature CF1700C

Little Leon lives in the forest. He has recently noticed that some trees near his favourite path are withering, while the other ones are overhydrated so he decided to learn how to control the level of the soil moisture to save the trees.

There are nn trees growing near the path, the current levels of moisture of each tree are denoted by the array a1,a2,…,an. Leon has learned three abilities which will help him to dry and water the soil.

  • Choose a position i and decrease the level of moisture of the trees 1,2,…,i by 1.
  • Choose a position i and decrease the level of moisture of the trees i,i+1,…,n by 1.
  • Increase the level of moisture of all trees by 1.

Leon wants to know the minimum number of actions he needs to perform to make the moisture of each tree equal to 0.

Input

The first line contains a single integer tt (1≤t≤2⋅10^4)  — the number of test cases. The description of tt test cases follows.

The first line of each test case contains a single integer nn (1≤n≤200000).

The second line of each test case contains nn integers a1,a2,…,an (−10^9≤ai≤10^9) — the initial levels of trees moisture.

It is guaranteed that the sum of nn over all test cases doesn't exceed 200000.

Output

For each test case output a single integer — the minimum number of actions. It can be shown that the answer exists.

Example

input

4
3
-2 -2 -2
3
10 4 7
4
4 -4 4 -4
5
1 -2 3 -4 5

output

2
13
36
33

Note

In the first test case it's enough to apply the operation of adding 1 to the whole array 2 times.

In the second test case you can apply the operation of decreasing 4 times on the prefix of length 3 and get an array 6,0,3.

After that apply the operation of decreasing 6 times on the prefix of length 1 and 3 times on the suffix of length 1. In total, the number of actions will be 4+6+3=13. It can be shown that it's impossible to perform less actions to get the required array, so the answer is 13.

题意: 给出一个数组,每次操作可以选择1. 让一个前缀全部-1,2. 让一个后缀全部-1,3. 让数组整体+1,求最少多少次操作使数组为0。

分析: 如果想到用差分数组会比较好解决,求出数组a的差分数组d后,只需要让d[2]~d[n]全变为0,三种操作在d数组上的影响分别是:d[1]--&&d[x+1]++, d[x]--, d[1]++,如果d[2]~d[n]中出现了非0,那么一定要通过前两种操作变为0,这个次数其实就是sum(abs(d[i]), i>=2),然后此时d[1]可能为正或负,如果d[1]是正那就整体多次-1,如果d[1]为负那就整体多次+1,最终d数组全部为0,此时操作的次数就是最终答案。

具体代码如下: 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;

long long a[200005], d[200005];

signed main()
{
	int T;
	cin >> T;
	while(T--){
		int n;
		scanf("%d", &n);
		long long ans = 0;
		for(int i = 1; i <= n; i++){
			scanf("%lld", &a[i]);
			d[i] = a[i]-a[i-1];
			if(i >= 2){
				ans += abs(d[i]);
				if(d[i] < 0) d[1] += d[i];
			}
		}
		ans += abs(d[1]);
		printf("%lld\n", ans);
	}
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值