Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <bits/stdc++.h>
- #include <vector>
- #include <algorithm>
- #include <cstring>
- #include <map>
- using namespace std;
- typedef long long ll;
- const int maxn = 2e5 + 10;
- int a[maxn];
- int block_size;
- ll result;
- ll freq[maxn];
- struct query {
- int L, R, idx, b;
- query() {}
- query(int _L, int _R, int _idx, int _b) {
- L = _L;
- R = _R;
- idx = _idx;
- b = _b;
- }
- bool operator < (const query & q) const {
- if(b != q.b) {
- return b < q.b;
- }
- if(b % 2 == 1) {
- return R < q.R;
- }
- return R > q.R;
- }
- };
- void add(int idx) {
- ll f = freq[a[idx]];
- result += f * (f - 1) / 2;
- freq[a[idx]]++;
- }
- void remove(int idx) {
- freq[a[idx]]--;
- ll f = freq[a[idx]];
- result -= f * (f - 1) / 2;
- }
- int main() {
- ios_base::sync_with_stdio(false);
- int n, q;
- cin >> n >> q;
- for(int i = 1; i <= n; i++) {
- cin >> a[i];
- }
- block_size = max(1, int(n / sqrt(q)));
- vector<query> queries(q);
- for(int i = 0; i < q; i++) {
- cin >> queries[i].L >> queries[i].R;
- queries[i].idx = i;
- queries[i].b = queries[i].L / block_size;
- }
- sort(queries.begin(), queries.end());
- result = 0;
- int curr_L = 1, curr_R = 0;
- vector<ll> ans(q);
- for(int i = 0; i < q; i++) {
- int L = queries[i].L, R = queries[i].R;
- while(curr_L > L) {
- curr_L--;
- add(curr_L);
- }
- while(curr_R < R) {
- curr_R++;
- add(curr_R);
- }
- while(curr_L < L) {
- remove(curr_L);
- curr_L++;
- }
- while(curr_R > R) {
- remove(curr_R);
- curr_R--;
- }
- ans[queries[i].idx] = result;
- }
- for(int i = 0; i < q; i++) {
- cout << ans[i] << "\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment