【Codeforces 817D】Imbalanced Array
CF817D Imbalanced Array
链接
题目大意
求:
\[\sum_{l=1}^n\sum_{r=l}^n\left(\max_{i=l}^r\{a_i\}-\min_{i=l}^r\{a_i\}\right)
\]
思路
方法一
\(\mathcal{O}(n^3)\) 暴力。
方法二
先转化:
\[\begin{aligned}
\sum_{l=1}^n\sum_{r=l}^n\left(\max_{i=l}^r\{a_i\}-\min_{i=l}^r\{a_i\}\right)=\sum_{l=1}^n\sum_{r=l}^n\max_{i=l}^r\{a_i\}-\sum_{l=1}^n\sum_{r=l}^n\min_{i=l}^r\{a_i\}
\end{aligned}
\]
然后考虑用单调栈优化:对于最大和最小分别开两个单调栈,分别记录若当前点为区间最大或最小的值,那么左右分别到哪个点,即找某个点左边、右边第一个比它大(或小)的值。
然后就能 \(\mathcal{O}(n)\) 做了。
代码
const int N = 1e6 + 10;
inline ll Read() {
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
ll n, a[N], qx[N], qn[N], tx, tn, f[N], g[N];
ll ans;
int main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
n = Read();
for (int i = 1; i <= n; i++) a[i] = Read();
for (int i = 1; i <= n; i++) {
for (; tx && a[qx[tx]] <= a[i]; tx--);
for (; tn && a[qn[tn]] >= a[i]; tn--);
qx[++tx] = i, qn[++tn] = i;
f[i] = i - qx[tx - 1];
g[i] = i - qn[tn - 1];
}
tx = tn = 0;
qx[0] = qn[0] = n + 1;
for (int i = n; i; i--) {
for (; tx && a[qx[tx]] < a[i]; tx--);
for (; tn && a[qn[tn]] > a[i]; tn--);
qx[++tx] = i, qn[++tn] = i;
ans += a[i] * (qx[tx - 1] - i) * f[i] - a[i] * (qn[tn - 1] - i) * g[i];
}
printf ("%lld\n", ans);
return 0;
}