1. 程式人生 > 其它 >AtCoder Regular Contest 119 E - Pancakes

AtCoder Regular Contest 119 E - Pancakes

題目連結:點我點我


Score: 800 points

Problem Statement

We have a pancake tower which is a pile of N pancakes. Initially, the i-th pancake from the top (1iN) has a size of Ai. Takahashi, a chef, can do the following operation at most once.

  • Choose integers l and r (1l<rN) and turn the
    l
    -th through r-th pancakes upside down, reversing the order.

Find the minimum possible ugliness of the tower after the operation is done (or not), defined below:

the ugliness is the sum of the differences of the sizes of adjacent pancakes;
that is, the value |A1

A2|+|A2A3|++|AN1AN|, where Ai is the size of the i-th pancake from the top.

Constraints

  • 2N300000
  • 1Ai109
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A1 A2  AN

Output

Print the minimum possible ugliness of the tower.


Sample Input 1

5
7 14 12 2 6

Sample Output 1

17

If we do the operation choosing l=2 and r=5, the pancakes will have the sizes of 7,6,2,12,14 from top to bottom.

The ugliness here is |76|+|62|+|212|+|1214|=1+4+10+2=17. This is the minimum value possible; there is no way to achieve less ugliness.


Sample Input 2

3
111 119 999

Sample Output 2

888

In this sample, not doing the operation minimizes the ugliness.

In that case, the pancakes will have the sizes of 111,119,999 from top to bottom, for the ugliness of |111119|+|119999|=8+880=888.


Sample Input 3

6
12 15 3 4 15 7

Sample Output 3

19

If we do the operation choosing l=3 and r=5, the pancakes will have the sizes of 12,15,15,4,3,7 from top to bottom.

The ugliness here is |1215|+|1515|+|154|+|43|+|37|=3+0+11+1+4=19, which is the minimum value possible.


Sample Input 4

7
100 800 500 400 900 300 700

Sample Output 4

1800

If we do the operation choosing l=2 and r=4, the pancakes will have the sizes of 100,400,500,800,900,300,700 from top to bottom, for the ugliness of 1800.


Sample Input 5

10
535907999 716568837 128214817 851750025 584243029 933841386 159109756 502477913 784673597 603329725

Sample Output 5

2576376600



給出 n 個數,然後可以旋轉一個區間,使得旋轉後的 a 陣列

\[|a_2-a_1|+|a_3-a_2|+|a_4-a_3|+....+|a_n-a_{n-1}| \]

最小


很容易可以發現當旋轉一個區間 \([i, j]\) 時,只有 \(|a[i]-a[i-1]|+|a[j]-a[j+1]|\) 變為了 \(|a[i]-a[j+1]|+|a[j]-a[i-1]|\) ,而中間的並沒有發生改變,所以這個問題只關心端點

看到這些絕對值,不由的想到距離,不妨將其在數軸上做一下分類討論,發現只有:

\[\begin{split} a_{i-1}<a_j<a_i<a_{j+1} \\ a_{i-1}<a_j<a_{j+1}<a_{i} \\ a_{i}<a_{j+1}<a_{i-1}<a_{j} \\ a_{i}<a_{j+1}<a_j<a_{i-1} \\ \end{split} \]

這此種情況時,才會使得結果變小;又是一道二位偏序,按左端點排個序,只討論右端點就可以解決問題了;

但是題目還有一個邊界問題 ,但 \(O(n)\) 足夠可以解決

總複雜度 \(O(NlogN)\)



const int N = 3e5 + 5;

    ll n, m, _;
    int i, j, k;
    ll a[N];

struct Seg{
    int l, r;
    int tag;
    Seg(){};
    Seg(int l, int r){
        tag = 0;
        if(l > r){
            swap(l, r);
            tag = 1;
        }
        this -> l = l;
        this -> r = r;
    }
} seg[N];

bool cmp(Seg a, Seg b)
{
    return a.l < b.l;
}

signed main()
{
    //IOS;
    while (~sd(n)) {
        rep(i, 1, n) sll(a[i]);
        for (int i = 1; i < n; i++) {
            seg[i] = Seg(a[i], a[i + 1]);
        }
        sort(seg + 1, seg + n, cmp);
        //for(int i=1;i<n;i++) dbg(seg[i].l), dbg(seg[i].r);

        ll maxx = 0, ed[2] = {0, 0};
        for(int i = 1; i < n; i++){
            int tag = seg[i].tag;
            if(ed[tag] == 0){
                ed[tag] = seg[i].r;
                continue;
            }
            if(seg[i].r <= ed[tag]){
                maxx = max(maxx, 1ll * seg[i].r - seg[i].l);
                continue;
            }
            if(seg[i].r > ed[tag]){
                maxx = max(maxx, ed[tag] - seg[i].l);
            }
            ed[tag] = max(ed[tag], 1ll * seg[i].r);
        }
        ll ans = 0;
        for(int i = 2; i <= n; i++){
            ans += abs(a[i] - a[i - 1]);
        }
        maxx *= 2;
        for(int i = 1; i < n; i++){
            maxx = max(maxx, abs(a[i] - a[i + 1]) - abs(a[i] - a[n]));
            maxx = max(maxx, abs(a[i + 1] - a[i]) - abs(a[i + 1] - a[1]));
        }
        pll(ans - maxx);
    }
    //PAUSE;
    return 0;
}