1. 程式人生 > >Imbalanced Array CodeForces - 817D (思維+單調棧)

Imbalanced Array CodeForces - 817D (思維+單調棧)

bec ces rep turn while nbsp dash 思維 you

You are given an array a consisting of n elements. The imbalance value of some subsegment of this array is the difference between the maximum and minimum element from this segment. The imbalance value of the array is the sum of imbalance valuesof all subsegments of this array.

For example, the imbalance value of array [1, 4, 1] is 9, because there are 6different subsegments of this array:

  • [1] (from index 1 to index 1), imbalance value is 0;
  • [1, 4] (from index 1 to index 2), imbalance value is 3;
  • [1, 4, 1] (from index 1 to index 3), imbalance value is 3;
  • [4] (from index 2 to index 2), imbalance value is 0;
  • [4, 1] (from index 2 to index 3), imbalance value is 3;
  • [1] (from index 3 to index 3), imbalance value is 0;

You have to determine the imbalance value of the array a.

Input

The first line contains one integer n (1 ≤ n ≤ 106) — size of the array a.

The second line contains n integers a1, a2... an (1 ≤ a

i ≤ 106) — elements of the array.

Output

Print one integer — the imbalance value of a.

Example

Input
3
1 4 1
Output
9

題意:
給定一個含有N個數的數組,求這個數組的所有連續區間的不平衡值的總和。
一個區間的不平衡值為這個區間中的最大值減去最小值。
思路:
我們可以這樣思考,這個題目的答案可以這樣得來,
對於每一個a[i],它對答案的貢獻值為以a[i]為區間最大值的區間數量*a[i]-a[i]*以a[i]為區間最小值的區間數量。
ans=sum{ contribution(a[i])}

那麽我們的難題為如何計算以a[i]為區間最大/最小值的區間數量。
這種模型我們很容易想到利用單調棧來O(N)求出。
我們定義兩個數組,l[n+5],r[n+5],l[i]和r[i] 分別維護的是從a[i]元素開始向左和向右第一個比a[i]小的元素的位置。(註意邊界)
然後我們可以通過l[i]和r[i]來求出區間數量,然後我們再利用單調棧求出
從a[i]元素開始向左和向右第一個比a[i]大的元素的位置
然後我們愉快的計算每一個的貢獻然後加起來就是我們要求的答案。
細節見代碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define rt return
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), ‘\0‘, sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int n;
int a[maxn];
int l[maxn];
int r[maxn];
ll ans=0ll;
int main()
{
    gg(n);
    repd(i,1,n)
    {
        gg(a[i]);
    }
    stack<int> s;
    repd(i,1,n)
    {
        while(s.size()&&a[s.top()]>a[i])
        {
            s.pop();
        }
        if(s.size())
        {
            l[i]=s.top();
        }else
        {
            l[i]=0;
        }
        s.push(i);
    }
    while(s.size())
    {
        s.pop();
    }
    for(int i=n;i>=1;i--)
    {
        while(s.size()&&a[s.top()]>=a[i])
        {
            s.pop();
        }
        if(s.size())
        {
            r[i]=s.top();
        }else
        {
            r[i]=n+1;
        }
        s.push(i);
    }
    repd(i,1,n)
    {
        ans=ans-1ll*a[i]*(i-l[i])*(r[i]-i);
    }
//    db(ans);
    while(s.size())
    {
        s.pop();
    }
    repd(i,1,n)
    {
        while(s.size()&&a[s.top()]<a[i])
        {
            s.pop();
        }
        if(s.size())
        {
            l[i]=s.top();
        }else
        {
            l[i]=0;
        }
        s.push(i);
    }
    while(s.size())
    {
        s.pop();
    }
    for(int i=n;i>=1;i--)
    {
        while(s.size()&&a[s.top()]<=a[i])
        {
            s.pop();
        }
        if(s.size())
        {
            r[i]=s.top();
        }else
        {
            r[i]=n+1;
        }
        s.push(i);
    }

    repd(i,1,n)
    {
        ans=ans+1ll*a[i]*(i-l[i])*(r[i]-i);
    }
    printf("%lld\n",ans );
    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch ==   || ch == \n);
    if (ch == -) {
        *p = -(getchar() - 0);
        while ((ch = getchar()) >= 0 && ch <= 9) {
            *p = *p * 10 - ch + 0;
        }
    }
    else {
        *p = ch - 0;
        while ((ch = getchar()) >= 0 && ch <= 9) {
            *p = *p * 10 + ch - 0;
        }
    }
}



Imbalanced Array CodeForces - 817D (思維+單調棧)