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(单调栈)