Cod sursa(job #2656019)

Utilizator lflorin29Florin Laiu lflorin29 Data 6 octombrie 2020 16:37:29
Problema Distincte Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <bits/stdc++.h>

using namespace std;

const int MOD = 1e9 + 7;

void Mul (int &a, int b) {
    a = (a + b) % MOD;
}


class PersistentSegmentTree {
    struct Node {
        int l, r, prod;
    };
    vector<Node>aint;
    int free_idx, nn;
    vector<int>root;
  public:
    PersistentSegmentTree (const vector<int>&els) {
        int n = els.size();
        nn = n;
        aint = vector<Node> (n * log2 (n) + 200, Node{-1, -1, 0});
        root.resize (n);
        free_idx = 0;
        int pl = change (0, 0, n - 1, 0, els[0]);
        root[0] = pl;
        map<int, int>last;
        last[els[0]] = 0;

        for (int i = 1; i < (int) els.size(); ++i) {
            root[i] = change (root[i - 1], 0, n - 1, i, els[i]);
            if (last.find (els[i]) != end (last) )
                root[i] = change (root[i], 0, n - 1, last[els[i]], 0 );
            last[els[i] ] = i;
        }
    }
    int change (int id, int l, int r, int at, int value) {
        if (l == r) {
            ++free_idx;
            aint[free_idx].l = -1;
            aint[free_idx].r = -1;
            aint[free_idx].prod = value;
            return free_idx;
        }
        int m = (l + r) / 2;
        if (aint[id].l == -1)
            aint[id].l = ++free_idx;
        if (aint[id].r == -1)
            aint[id].r = ++free_idx;
        int ls = aint[id].l;
        int rs = aint[id].r;
        if (at <= m)
            ls = change (ls, l, m, at, value);
        else
            rs = change (rs, m + 1, r, at, value);
        ++free_idx;
        aint[free_idx].l = ls;
        aint[free_idx].r = rs;
        aint[free_idx].prod = 0;
        for (int son : {
                    ls, rs
                })
            Mul (aint[free_idx].prod, aint[son].prod);
        return free_idx;
    }
    int qry (int id, int l, int r, int qx, int qy) {
        if (qx > r || l > qy)
            return 0;
        if (l >= qx && r <= qy)
            return aint[id].prod;
        int m = (l + r) >> 1;
        int rez = qry (aint[id].l, l, m, qx, qy);
        Mul (rez, qry (aint[id].r, m + 1, r, qx, qy) );
        return rez;
    }
    int qry (int l, int r) {
        return qry (root[r], 0, nn - 1, l, r);
    }
};

int32_t main() {
ifstream cin("distincte.in");
ofstream cout("distincte.out");


    int n, k, m;
    cin >> n >> k >> m;
    vector<int>a (n);
    for (int i = 0; i < n; ++i)
        cin >> a[i];
    PersistentSegmentTree PST (a);
    for (int i = 0; i < m; ++i) {
        int l, r;
        cin >> l >> r;
        cout << PST.qry (l - 1, r - 1) << '\n';
    }

}