Cod sursa(job #2877050)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 24 martie 2022 08:58:40
Problema Secventa 5 Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.64 kb
//
// Created by Mihai145 on 3/24/2022.
//

#include <fstream>

#include <vector>
#include <deque>
#include <unordered_map>

void push_val_back(std::deque<int> &d, std::unordered_map<unsigned int, int> &m, int &count_dist, std::vector<unsigned int> &v,
                   const int &pos) {
    d.push_back(pos);

    if (m[v[pos]] == 0) {
        count_dist++;
    }
    m[v[pos]]++;
}

void push_val_front(std::deque<int> &d, std::unordered_map<unsigned int, int> &m, int &count_dist, const std::vector<unsigned int> &v,
                    const int &pos) {
    d.push_front(pos);

    if (m[v[pos]] == 0) {
        count_dist++;
    }
    m[v[pos]]++;
}

int pop_val(std::deque<int> &d, std::unordered_map<unsigned int, int> &m, int &count_dist, const std::vector<unsigned int> &v) {
    if (m[v[d.front()]] == 1) {
        count_dist--;
    }
    m[v[d.front()]]--;

    int r = d.front();
    d.pop_front();

    return r;
}

class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;

    char read_ch() {
        ++sp;
        if (sp == 4096) {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }

public:
    InParser(const char* nume) {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }

    InParser& operator >> (unsigned int &n) {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser& operator >> (long long &n) {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-');
        long long sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
};

int main() {
    InParser cin("secv5.in");
    std::ofstream cout("secv5.out");

    int N, L, U;
    cin >> N >> L >> U;

    std::vector<unsigned int> v(N + 1, 0);
    for (int i = 1; i <= N; ++i) {
        cin >> v[i];
    }

    std::deque<int> dq_l_max, dq_l_min;
    std::unordered_map<unsigned int, int> freq_l_max, freq_l_min;
    int count_dist_max = 0, count_dist_min = 0;

    long long sol = 0;
    for (int i = 1; i <= N; ++i) {
        push_val_back(dq_l_max, freq_l_max, count_dist_max, v, i);
        push_val_back(dq_l_min, freq_l_min, count_dist_min, v, i);

        while (count_dist_max > U) {
            pop_val(dq_l_max, freq_l_max, count_dist_max, v);
        }

        int last_popped = -1;
        while (count_dist_min >= L) {
            last_popped = pop_val(dq_l_min, freq_l_min, count_dist_min, v);
        }
        if (last_popped != -1) {
            push_val_front(dq_l_min, freq_l_min, count_dist_min, v, last_popped);
        }

        if (count_dist_min >= L) {
            sol += (dq_l_min.front() - dq_l_max.front() + 1);
        }
    }
    cout << sol;

    return 0;
}