-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path8462.cpp
More file actions
54 lines (50 loc) · 1.22 KB
/
8462.cpp
File metadata and controls
54 lines (50 loc) · 1.22 KB
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
/*
8462
Sqrt decomposition, Mo's algorithm
http://highalps.tistory.com/11
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
int h;
struct dot {
int l, r, id;
bool operator<(const dot& A) const {
return l / h == A.l / h ? r < A.r : l / h < A.l / h;
}
} query[100001];
ll res[100001];
int cnt[1000001];
ll move(int t, int val) {
cnt[val] += t;
return ((ll)2 * (ll)t * (ll)cnt[val] - 1) * (ll)val;
}
int main() {
int n, k, l, r;
scanf("%d %d", &n, &k);
h = sqrt(n);
vector<ll> a(n + 1, 0);
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
for (int i = 0; i < k; i++) {
scanf("%d %d", &query[i].l, &query[i].r);
query[i].id = i;
}
sort(query, query + k);
ll sum = 0;
l = query[0].l, r = query[0].r;
for (int i = l; i <= r; i++) sum += move(1, a[i]);
res[query[0].id] = sum;
for (int i = 1; i < k; i++) {
while (l > query[i].l) sum += move(1, a[--l]);
while (l < query[i].l) sum += move(-1, a[l++]);
while (r > query[i].r) sum += move(-1, a[r--]);
while (r < query[i].r) sum += move(1, a[++r]);
res[query[i].id] = sum;
}
for (int i = 0; i < k; i++) printf("%lld\n", res[i]);
return 0;
}