Cod sursa(job #3271805)

Utilizator EricDimiericdc EricDimi Data 27 ianuarie 2025 13:40:30
Problema Secventa 5 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("secv5.in");
ofstream g("secv5.out");

const uint32_t MAX_DIM = (1 << 20);
const uint32_t MOD = 666013;

uint32_t v[MAX_DIM];
uint32_t n, l, u;

struct Elem
{
    uint32_t num;
    uint32_t fr;
};

class HashTable
{
    private:
        uint32_t head[MOD];
        Elem key[MAX_DIM];
        uint32_t nxt[MAX_DIM];
        uint32_t crt;
        uint32_t mod;

    public:
        HashTable(uint32_t _mod)
        {
            mod = _mod;
            crt = 0;
            for (uint32_t i = 0; i < mod; i++)
                head[i] = -1;
            for (uint32_t i = 0; i < MAX_DIM; i++)
                nxt[i] = -1;
        }

        void init(uint32_t _mod)
        {
            mod = _mod;
            crt = 0;
            for (uint32_t i = 0; i < mod; i++)
                head[i] = -1;
            for (uint32_t i = 0; i < MAX_DIM; i++)
            {
                nxt[i] = -1;
                key[i].fr = 0;
            }
        }

        uint32_t getKey(uint32_t x) {
            return x % mod;
        }

        uint32_t add(uint32_t x)
        {
            uint32_t list_idx = getKey(x);
            uint32_t it = head[list_idx];
            uint32_t res = 0;
            while (it != -1 && key[it].num != x)
                it = nxt[it];
            if (it != -1)
                ++key[it].fr;
            else
            {
                key[crt].num = x;
                key[crt].fr = 1;
                nxt[crt] = head[list_idx];
                head[list_idx] = crt;
                ++crt;
                res = 1;
            }
            return res;
        }

        uint32_t find_element(uint32_t x)
        {
            uint32_t list_idx = getKey(x);
            uint32_t it = head[list_idx];
            while (it != -1 && key[it].num != x)
                it = nxt[it];
            return (it != -1);
        }

        uint32_t erase_element(uint32_t x)
        {
            uint32_t list_idx = getKey(x);
            uint32_t prev = head[list_idx], it = nxt[prev];
            uint32_t res = 0;
            if (key[prev].num == x)
            {
                --key[prev].fr;
                if (!key[prev].fr)
                {
                    head[list_idx] = nxt[prev];
                    res = 1;
                }
            }
            else
            {
                while (it != -1 && key[it].num != x)
                {
                    prev = it;
                    it = nxt[it];
                }
                if (it != -1)
                {
                    --key[it].fr;
                    if (!key[it].fr)
                    {
                        nxt[prev] = nxt[it];
                        res = 1;
                    }
                }
            }
            return res;
        }

};

HashTable hash_table(0);

uint64_t nrSecv(uint32_t x)
{
    hash_table.init(MOD);
    uint32_t nr_distinct = 0, st = 0;
    uint64_t cnt = 0;
    for (uint32_t dr = 0; dr < n; dr++)
    {
        nr_distinct += hash_table.add(v[dr]);
        while (st <= dr && nr_distinct > x)
            nr_distinct -= hash_table.erase_element(v[st++]);
        cnt += (uint64_t)(dr - st + 1);
    }
    return cnt;
}

int main()
{
    f >> n >> l >> u;
    for (uint32_t i = 0; i < n; i++)
        f >> v[i];
    g << nrSecv(u) - nrSecv(l - 1) << '\n';
    f.close();
    g.close();
    return 0;
}