Cod sursa(job #3134491)

Utilizator stefan.popescuPopescu Stefan stefan.popescu Data 29 mai 2023 10:03:55
Problema Distincte Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <bits/stdc++.h>

using namespace std;

int n, k, m;

struct segNode {
    long long sum;
    segNode(int x = 0, int y = 0) : sum(x) {}
    friend segNode operator+(const segNode &s1, const segNode &s2) {
        return segNode(s1.sum + s2.sum);
    }
};

class segTree {
private:
    int segSize;
    vector<segNode> seg;
    void pointUpdateUtil(int p, int l, int r, int lQ, int rQ, long long vQ) {
        int m = (l + r) / 2;
        if (lQ > r || rQ < l)
            return;

        if (lQ <= l && r <= rQ) {
            seg[p].sum += vQ;
            return;
        }

        pointUpdateUtil(p + 1, l, m, lQ, rQ, vQ);
        pointUpdateUtil(p + 2 * (m - l + 1), m + 1, r, lQ, rQ, vQ);

        seg[p] = seg[p + 1] + seg[p + 2 * (m - l + 1)];
    }
    segNode rangeQueryUtil(int p, int l, int r, int lQ, int rQ) {
        int m = (l + r) / 2;
        if (lQ <= l && r <= rQ)
            return seg[p];
        if (lQ <= m && m + 1 <= rQ)
            return rangeQueryUtil(p + 1, l, m, lQ, rQ) + rangeQueryUtil(p + 2 * (m - l + 1), m + 1, r, lQ, rQ);
        else if (lQ <= m)
            return rangeQueryUtil(p + 1, l, m, lQ, rQ);
        else
            return rangeQueryUtil(p + 2 * (m - l + 1), m + 1, r, lQ, rQ);
    }

public:
    segTree(int n) {
        seg.resize(2 * n);
        segSize = n;
    }
    void rangeUpdate(int l, int r, long long x) {
        pointUpdateUtil(0, 0, segSize - 1, l, r, x);
    }
    segNode rangeQuery(int l, int r) {
        return rangeQueryUtil(0, 0, segSize - 1, l, r);
    }
};

const int nmax = 1e5;

int a[nmax + 2];
int lastMet[nmax + 2];

vector<tuple<int, int, int> > vec;

long long ans[nmax + 2];

void solve(){
    cin >> n >> k >> m;
    for(int i = 0; i < n; i++)
        cin >> a[i];
    fill(lastMet, lastMet + n + 1, -1);
    segTree arb(n);
    for(int i = 1; i <= m; i++){
        int x, y;
        cin >> x >> y;
        vec.emplace_back(x - 1, y - 1, i);
    }
    sort(vec.begin(), vec.end(), [&](const tuple<int, int, int> & x1, const tuple<int, int, int> & x2){
        return get<1>(x1) < get<1>(x2);
    });
    int lPtr = -1;
    for(auto &tpl:vec){
        while(lPtr < get<1>(tpl)){
            lPtr++;
            if(lastMet[a[lPtr]] != -1)
                arb.rangeUpdate(lastMet[a[lPtr]], lastMet[a[lPtr]], -a[lPtr]);
            lastMet[a[lPtr]] = lPtr;
            arb.rangeUpdate(lastMet[a[lPtr]], lastMet[a[lPtr]], +a[lPtr]);
        }
        ans[get<2>(tpl)] = arb.rangeQuery(get<0>(tpl), get<1>(tpl)).sum;
    }
    for(int i = 1; i <= m; i++)
        cout << ans[i] << "\n";
}

int32_t main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0), cerr.tie(0);
    freopen("distincte.in", "r", stdin);
    freopen("distincte.out", "w", stdout);

    int q = 1;
    // cin >> q;
    while(q--){
        solve();
    }
    return 0;
}