P10162 题解
Register_int · · 题解
考虑分治。设当前处理
考虑直接以
拆贡献,考虑有多少对区间满足其价值等于
然后事实上你发现第二只
AC 代码
#include <bits/stdc++.h>
using namespace std;
typedef unsigned uint;
const int MAXN = 1e6 + 10;
int n, a[MAXN], id[MAXN], t[MAXN], tot;
int b[MAXN]; uint ans, c[MAXN];
void solve(int l, int r) {
if (l == r) return ;
int mid = l + r >> 1; solve(l, mid), solve(mid + 1, r);
for (int i = mid, p = -1e18; i >= l; i--) {
b[i] = max(p, a[i] - a[i + 1]);
p = max(p, a[i] - max(a[i - 1], a[i + 1]));
}
for (int i = mid + 1, p = -1e18; i <= r; i++) {
b[i] = max(p, a[i] - a[i - 1]);
p = max(p, a[i] - max(a[i - 1], a[i + 1]));
}
tot = 0;
for (int i = l; i <= r; i++) t[++tot] = b[i];
sort(t + 1, t + tot + 1), tot = unique(t + 1, t + tot + 1) - t - 1;
for (int i = l; i <= r; i++) id[i] = lower_bound(t + 1, t + tot + 1, b[i]) - t;
for (int i = mid + 1; i <= r; i++) c[id[i]]++;
for (int i = 1; i <= tot; i++) c[i] += c[i - 1];
for (int i = l; i <= mid; i++) ans += (uint)b[i] * c[id[i]];
for (int i = 1; i <= tot; i++) c[i] = 0;
for (int i = l; i <= mid; i++) c[id[i]]++;
for (int i = 1; i <= tot; i++) c[i] += c[i - 1];
for (int i = mid + 1; i <= r; i++) ans += (uint)b[i] * c[id[i] - 1];
for (int i = 1; i <= tot; i++) c[i] = 0;
}
int main() {
scanf("%lld", &n);
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
solve(1, n), printf("%u", ans);
}