差分数组操作的一些性质

Problem - C - Codeforces

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,…,ana1,a2,…,an. Leon has learned three abilities which will help him to dry and water the soil.

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

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

Input

The first line contains a single integer tt (1≤t≤2⋅1041≤t≤2⋅104)  — 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≤2000001≤n≤200000).

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

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

Output

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

Example

input

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

output

Copy

2
13
36
33

Note

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

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

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

058e21e7f5c2494382ba0238537cf92b.png

 

 

LL a[N], d[N];
LL t, n, res;
int main()
{
    ios_base::sync_with_stdio(0), cin.tie(0);
    cin >> t;
    while (t--)
    {
        res = 0;
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];

        for (int i = 1; i <= n; i++)
            d[i] = a[i] - a[i-1];

        for (int i = 2; i <= n; i++)
        {
            if (d[i] < 0)
            {
                res -= d[i];
                d[1] += d[i];
            }
            else
                res += d[i];
        }
        cout << res + abs(d[1]) << endl;
    }
    system("pause");
    return 0;
}

下面也是一道利用差分数组性质的一道题 

AcWing 100.增减序列

int n, a[N], d[N];
signed main()
{
    FAST;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        d[i] = a[i] - a[i - 1];
    }

    int p = 0, q = 0;
    for (int i = 2; i <= n; i++)
    {
        if (d[i] >= 0)
            p += d[i];
        else
            q -= d[i];
    }

    cout << max(p, q) << endl;
    // 执行max(p, q)次操作后剩余|p - q|个d[i]没有变成0
    // 要改变剩下的k个d[i]就要操作d[1 ~ i]使d[1] += 1, d[i] -= 1
    // 这样就会得到k个不同的d[1]
    cout << abs(p - q) + 1;

    return 0;
}

相关题解

总的来说要想连续改变一段区间的数值大小,可以利用差分数组使复杂度降到O(1);

根据差分数组原理:改变[ L ~ R ]区间的数,只需要使d[ L ] 操作一次,d[ R + 1 ]操作一次

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值