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;
}

posted @ 2018-08-14 23:14  谜のNOIP  阅读(74)  评论(0编辑  收藏  举报