1. 程式人生 > >Codeforces Round #508 (Div. 2) D. Slime

Codeforces Round #508 (Div. 2) D. Slime

D. Slime

There are nn slimes in a row. Each slime has an integer value (possibly negative or zero) associated with it.

Any slime can eat its adjacent slime (the closest slime to its left or to its right, assuming that this slime exists).

When a slime with a value xx eats a slime with a value yy, the eaten slime disappears, and the value of the remaining slime changes to x−yx−y.

The slimes will eat each other until there is only one slime left.

Find the maximum possible value of the last slime.

Input

The first line of the input contains an integer nn (1≤n≤5000001≤n≤500000) denoting the number of slimes.

The next line contains nn integers aiai (−109≤ai≤109−109≤ai≤109), where aiai is the value of ii-th slime.

Output

Print an only integer — the maximum possible value of the last slime.

Examples

input

Copy

4
2 1 2 1

output

Copy

4

input

Copy

5
0 -1 -1 -1 -1

output

Copy

4

題意:給你n個數,任意相鄰兩數作差x=a[i]-a[j],只要i!=j即可作差,所得x將代替原來的a[i],a[j],最終會剩下一個數,問你這個數最大是多少?

思路:一開始以為是dp,推了幾組資料發現有規律的。

我們可以分為三類:全是正數,全是負數,正負都有。

對於1,2,3,4,我們推一下會發現,無論怎麼排列這幾個數,最終都能求得最大值8.

1.所以如果整個陣列都是正號的,直接排序,讓x=a[1]-a[2]構造一個負數,接下來x=x-a[j](j>=3&&j<n)積累這個差,會積累到一個特別小的負數,用a[n]-x即為最大值。整個陣列負號的可以全變正號,直接用上面的方法。

2.對於異號的陣列,依然排序,找到最大的負數,即從右向左查,出現的第一個負數x,位置pos。由於x的右邊全是正數,那麼繼x=x-a[j],去積累差,最後x=a[n]-x,得到目前最大。接下來用x直接減去pos以左的全部負數,即得最大值。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll a[500050],n;
int main()
{
    while(~scanf("%lld",&n))
    {
        for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
        if(n==1){printf("%lld\n",a[1]);continue;}
        sort(a+1,a+n+1);
        ll f1,f2,sum;
        f1=f2=0;
        for(ll i=1;i<=n;i++)
        {
            if(a[i]>=0)f1=1;   //代表有正數和0
            if(a[i]<0)f2=1;   //代表有負數
        }
        if(f1&&f2==0)   //只有正數時
        {
            sum=a[1];
            for(ll i=2;i<=n;i++)
            {
                sum=sum-a[i];   //積累差
            }
            sum=-sum;
        }
        else if(f1==0&&f2)   //只有負數時
        {
            for(ll i=1;i<=n;i++)a[i]=-a[i];
            sort(a+1,a+n+1);
            sum=a[1];
            for(ll i=2;i<=n;i++)
            {
                sum=sum-a[i];
            }
            sum=-sum;
        }
        else
        {
            ll pos;
            for(ll i=n;i>=1;i--)   //找到右邊第一個負數pos
            {
                if(a[i]<=0)
                {
                    pos=i;
                    break;
                }
            }
            sum=a[pos];
            for(ll i=pos+1;i<=n;i++)
            {
                sum=sum-a[i];   //積累差
            }
            sum=-sum;
            for(ll i=1;i<pos;i++)sum-=a[i];   //向左積累回去
        }
        printf("%lld\n",sum);
    }
    return 0;
}