CF817D Imbalanced Array

Posted starroadtang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF817D Imbalanced Array相关的知识,希望对你有一定的参考价值。

题目链接

https://codeforces.com/contest/817/problem/D

题目大意

给你一个序列,让你求出这个序列的每个区间最大值的和 - 最小值的和

解题思路

单调栈

单调栈经典问题。

我们先求出以 a[ i ] 为最小值的左右最长拓展 L1[i] , R1[i]

那么以 a[ i ] 为最小值的区间个数就为 (L1[ i ] + 1) * (R1[ i ] + 1)

再求出以 a[ i ] 为最大值的左右最长拓展 L2[ i ] , R2[ i ]

那么以 a[ i ] 为最大值的区间个数就为 (L2[ i ] + 1) * (R2[ i ] + 1)

最后线性扫一遍即可

(为了避免相同值区间长度被重复计算,需采用左开右闭的维护方式)

AC_Coder

#include<bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define int long long
using namespace std;
const int N = 1e6 + 10;
int a[N] , sta[N] , l[N] , r[N] , ans;
signed main()
{
    int n ;
    cin >> n;
    rep(i , 1 , n) cin >> a[i];
    int top = 0;
    rep(i , 1 , n)
    {
        while(top && a[sta[top]] >= a[i]) top -- ;
        if(!top) l[i] = i - 1;
        else l[i] = i - sta[top] - 1;
        sta[++ top] = i;
    }
    top = 0;
    per(i , n , 1)
    {
        while(top && a[sta[top]] > a[i]) top --;
        if(!top) r[i] = n - i;
        else r[i] = sta[top] - i - 1;
        sta[++ top] = i;
    }  
    rep(i , 1 , n)
        ans -= a[i] * (l[i] + 1) * (r[i] + 1);
    top = 0;
    rep(i , 1 , n)
    {
        while(top && a[sta[top]] <= a[i]) top -- ;
        if(!top) l[i] = i - 1;
        else l[i] = i - sta[top] - 1;
        sta[++ top] = i;
    }
    top = 0;
    per(i , n , 1)
    {
        while(top && a[sta[top]] < a[i]) top --;
        if(!top) r[i] = n - i;
        else r[i] = sta[top] - i - 1;
        sta[++ top] = i;
    }  
    rep(i , 1 , n)
        ans += a[i] * (l[i] + 1) * (r[i] + 1);
    cout << ans << 
;
    return 0;
}

以上是关于CF817D Imbalanced Array的主要内容,如果未能解决你的问题,请参考以下文章

Imbalanced Array CodeForces - 817D (思维+单调栈)

CodeForces - 817D Imbalanced Array(单调栈)

Educational Codeforces Round 23 D. Imbalanced Array

codeforces-817 D. Imbalanced Array(单调栈)

codeforces-817 D. Imbalanced Array(单调栈)

codeforces-817 D. Imbalanced Array(单调栈)