Cod sursa(job #2700029)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 26 ianuarie 2021 13:23:05
Problema Secventa 5 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <fstream>

using namespace std;

const int N = 1 << 20;
const int MOD = 666019;

unsigned v[N];
pair<unsigned, int> val[N + 1]; //first - val, second - aparitii
int dl[N], du[N], lst[MOD], urm[N], nr = 0;

int cauta(unsigned x) {
    int c = x % MOD, p = lst[c];
    while (p && val[p].first != x)
        p = urm[p];
    if (p)
        return p;
    return -1;
}

bool adauga(unsigned x) { //false - exista, true - nu exista deja
    int p = cauta(x);
    if (p != -1) {
        ++val[p].second;
        return false;
    }
    
    int c = x % MOD;
    val[++nr] = { x, 1 };
    urm[nr] = lst[c];
    lst[c] = nr;
    return true;
}

bool exista(unsigned x) {
    int p = cauta(x);
    if (p == -1)
        return false;
    return true;
}

void sterge(unsigned x) {
    int p = cauta(x);
    if (p == -1)
        return;
    if (val[p].second > 1) {
        --val[p].second;
        return;
    }
    int c = x % MOD;
    swap(val[p], val[lst[c]]);
    lst[c] = urm[lst[c]];
}

void clear() {
    nr = 0;
    for (int i = 0; i < MOD; ++i)
        lst[i] = 0;
}

int main() {
    ifstream in("secv5.in");
    ofstream out("secv5.out");
    
    int n, l, u;
    in >> n >> l >> u;
    for (int i = 0; i < n; ++i)
        in >> v[i];
    in.close();
    
    int j = 0, dif = 0;
    for (int i = 0; i < n; ++i) {
        if (adauga(v[i]))
            ++dif;
        while (j <= i && dif >= l) {
            sterge(v[j]);
            if (!exista(v[j]))
                --dif;
            ++j;
        }
        if (dif == l - 1)
            dl[i] = j;
        else
            dl[i] = -1;
    }
    
    j = dif = 0;
    clear();
    for (int i = 0; i < n; ++i) {
        if (adauga(v[i]))
            ++dif;
        while (j <= i && dif > u) {
            sterge(v[j]);
            if (!exista(v[j]))
                --dif;
            ++j;
        }
        du[i] = j;
    }
    
    long long rez = 0;
    for (int i = 0; i < n; ++i)
        if (dl[i] > du[i])
            rez += dl[i] - du[i];
    
    out << rez;
    out.close();
    return 0;
}