bzoj 3781 小B的询问 莫队
题面
解法
同小Z的袜子
代码
#include <bits/stdc++.h>
#define int long long
#define N 50010
using namespace std;
template <typename node> void read(node &x) {
x = 0; int f = 1; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
while (isdigit(c)) x = x * 10 + c - '0', c = getchar(); x *= f;
}
struct Node {
int l, r, id;
} b[N];
int sum, a[N], s[N], ans[N], col[N];
bool cmp(Node x, Node y) {
return col[x.l] ^ col[y.l] ? col[x.l] < col[y.l] : col[x.l] & 1 ? x.r < y.r : x.r > y.r;
}
void update(int x, int v) {
sum += 2 * s[a[x]] * v + v * v;
s[a[x]] += v;
}
main() {
int n, q, k; read(n), read(q), read(k);
int siz = n / sqrt(q * 2 / 3);
for (int i = 1; i <= n; i++)
read(a[i]), col[i] = (i + siz - 1) / siz;
for (int i = 1; i <= q; i++)
read(b[i].l), read(b[i].r), b[i].id = i;
sort(b + 1, b + q + 1, cmp);
for (int i = 1, l = 1, r = 0; i <= q; i++) {
while (r < b[i].r) update(++r, 1);
while (r > b[i].r) update(r--, -1);
while (l < b[i].l) update(l++, -1);
while (l > b[i].l) update(--l, 1);
ans[b[i].id] = sum;
}
for (int i = 1; i <= q; i++) cout << ans[i] << "\n";
return 0;
}