【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 2000005 template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } struct Segment_Tree { struct Node { int lc, rc; long long sum, len, add, cnt; bool clear; } a[MAXN]; int n, root, size; void build(int root, int l, int r) { a[root].len = r - l + 1; if (l == r) return; int mid = (l + r) / 2; a[root].lc = ++size; build(size, l, mid); a[root].rc = ++size; build(size, mid + 1, r); } void init(int x) { n = x; root = size = 0; build(root, 0, 2 * n); } long long func(long long len) { return len * (len - 1) / 2; } void pushdown(int root) { if (a[root].clear) { int tmp = a[root].lc; a[tmp].add = 0; a[tmp].sum = 0; a[tmp].cnt = 0; a[tmp].clear = true; tmp = a[root].rc; a[tmp].add = 0; a[tmp].sum = 0; a[tmp].cnt = 0; a[tmp].clear = true; a[root].clear = false; } if (a[root].add) { int tmp = a[root].lc; a[tmp].add += a[root].add; a[tmp].sum += a[tmp].len * a[root].add; tmp = a[root].rc; a[tmp].add += a[root].add; a[tmp].sum += a[tmp].len * a[root].add; a[root].add = 0; } if (a[root].cnt) { int tmp = a[root].lc; a[tmp].cnt += a[root].cnt; a[tmp].sum += func(a[tmp].len) * a[root].cnt; tmp = a[root].rc; a[tmp].cnt += a[root].cnt; a[tmp].add += a[root].cnt * a[a[root].lc].len; a[tmp].sum += func(a[tmp].len) * a[root].cnt + a[root].cnt * a[a[root].lc].len * a[tmp].len; a[root].cnt = 0; } } void update(int root) { a[root].sum = a[a[root].lc].sum + a[a[root].rc].sum; } void ModifyCnt(int root, int l, int r, int ql, int qr, long long d, long long extra) { if (l == ql && r == qr) { a[root].cnt += d; a[root].add += d * extra; a[root].sum += func(a[root].len) * d + extra * d * a[root].len; return; } pushdown(root); int mid = (l + r) / 2, len = 0; if (mid >= ql) ModifyCnt(a[root].lc, l, mid, ql, min(qr, mid), d, extra), len = min(qr, mid) - ql + 1; if (mid + 1 <= qr) ModifyCnt(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, d, extra + len); update(root); } void ModifyAdd(int root, int l, int r, int ql, int qr, long long d) { if (l == ql && r == qr) { a[root].add += d; a[root].sum += a[root].len * d; return; } pushdown(root); int mid = (l + r) / 2; if (mid >= ql) ModifyAdd(a[root].lc, l, mid, ql, min(qr, mid), d); if (mid + 1 <= qr) ModifyAdd(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, d); update(root); } void modify(int l, int r, int d) { if (l > r) return; l += n, r += n; ModifyCnt(root, 0, 2 * n, l, r, d, 0); ModifyAdd(root, 0, 2 * n, r + 1, 2 * n, (r - l + 1) * d); } long long query(int root, int l, int r, int ql, int qr) { if (l == ql && r == qr) return a[root].sum; pushdown(root); long long ans = 0; int mid = (l + r) / 2; if (ql <= mid) ans += query(a[root].lc, l, mid, ql, min(mid, qr)); if (qr >= mid + 1) ans += query(a[root].rc, mid + 1, r, max(mid + 1, ql), qr); return ans; } long long query(int l, int r) { if (l > r) return 0; l += n, r += n; return query(root, 0, 2 * n, l, r); } void clear() { a[root].add = 0; a[root].cnt = 0; a[root].sum = 0; a[root].clear = true; } } SGT; vector <int> a[MAXN]; int n, type; int main() { read(n), read(type); for (int i = 0; i <= n - 1; i++) a[i].push_back(0); int value = 0; for (int i = 1; i <= n; i++) { int x; read(x); a[x].push_back(i); value = max(value, x); } for (int i = 0; i <= value; i++) a[i].push_back(n + 1); SGT.init(n); long long ans = 0; for (int i = 0; i <= value; i++) { SGT.modify(-a[i][1] + 1, 0, 1); for (unsigned j = 1; j <= a[i].size() - 2; j++) { int tmp = -a[i][j] + 2 * j; ans += SGT.query(tmp, tmp); SGT.modify(tmp, tmp, 1); ans += SGT.query(tmp - (a[i][j + 1] - a[i][j]) + 1, tmp - 1); SGT.modify(tmp - (a[i][j + 1] - a[i][j]) + 1, tmp - 1, 1); } SGT.clear(); } cout << ans << endl; return 0; }