1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #include <bits/stdc++.h> #define int long long using namespace std;
const int N = 2e5 + 66;
int n, res_minv, res_maxv; int a[N], pos[N]; int f[N][66], g[N][66];
inline void pres_dou() { int i, j; for (i = 1; i <= n; ++ i) f[i][0] = a[i], g[i][0] = a[i]; int t = log(n) / log(2) + 1; for (j = 1; j < t; ++ j) { for (i = 1; i <= n - (1 << j) + 1; ++ i) { f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]); g[i][j] = min(g[i][j - 1], g[i + (1 << (j - 1))][j - 1]); } } return; }
inline int query_maxv(int l, int r) { int k = log(r - l + 1) / log(2); return max(f[l][k], f[r - (1 << k) + 1][k]); }
inline int query_minv(int l, int r) { int k = log(r - l + 1) / log(2); return min(g[l][k], g[r - (1 << k) + 1][k]); }
inline void fuck_maxv(int l, int r) { if (l > r || l == r) return; int maxv = query_maxv(l ,r); res_maxv += 1ll * (1ll * (pos[maxv] - l) * (r - pos[maxv]) + (1ll * pos[maxv] - l) + (r - pos[maxv])) * maxv; fuck_maxv(l, pos[maxv] - 1); fuck_maxv(pos[maxv] + 1, r); return; }
inline void fuck_minv(int l, int r) { if (l > r || l == r) return; int minv = query_minv(l ,r); res_minv += 1ll * (1ll * (pos[minv] - l) * (r - pos[minv]) + (1ll * pos[minv] - l) + (r - pos[minv])) * minv; fuck_minv(l, pos[minv] - 1); fuck_minv(pos[minv] + 1, r); return; }
signed main() { int T = read(), i; while (T --) { memset(f, 0, sizeof f), memset(g, 0x3f, sizeof g); res_maxv = res_minv = 0; n = read(); for (i = 1; i <= n; ++ i) a[i] = read(), pos[a[i]] = i; pres_dou(); fuck_maxv(1, n), fuck_minv(1, n); put(res_maxv - res_minv); } return 0; }
|