Educational Codeforces Round 23 D. Imbalanced Array 单调栈

链接:

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

题意:

给你n个数a[1..n]定义连续子段imbalance值为最大值和最小值的差,要你求这个数组的imbalance总值

题解:

考虑每个位置作为最值向两边的最大拓展,最小值取负号,最大值取正号,求和即可。怎么去找呢?可以维护一个单调递增栈、单调递减栈

代码:

31 int n;
32 int a[MAXN];
33 int l_min[MAXN], r_min[MAXN], l_max[MAXN], r_max[MAXN];
34 
35 int main() {
36     ios::sync_with_stdio(false), cin.tie(0);
37     cin >> n;
38     rep(i, 1, n + 1) cin >> a[i];
39     l_min[1] = l_max[1] = 0;
40     rep(i, 2, n + 1) {
41         l_min[i] = l_max[i] = i - 1;
42         while (l_min[i] >= 1 && a[l_min[i]] > a[i])
43             l_min[i] = l_min[l_min[i]];
44         while (l_max[i] >= 1 && a[l_max[i]] < a[i])
45             l_max[i] = l_max[l_max[i]];
46     }
47     r_min[n] = r_max[n] = n + 1;
48     per(i, 0, n) {
49         r_min[i] = r_max[i] = i + 1;
50         while (r_min[i] <= n && a[r_min[i]] >= a[i])
51             r_min[i] = r_min[r_min[i]];
52         while (r_max[i] <= n && a[r_max[i]] <= a[i])
53             r_max[i] = r_max[r_max[i]];
54     }
55     ll ans = 0;
56     rep(i, 1, n + 1) {
57         ans -= 1LL * a[i] * (i - l_min[i])*(r_min[i] - i);
58         ans += 1LL * a[i] * (i - l_max[i])*(r_max[i] - i);
59     }
60     cout << ans << endl;
61     return 0;
62 }

 

posted @ 2017-08-15 17:09  Flowersea  阅读(149)  评论(0编辑  收藏  举报