Cod sursa(job #2155380)

Utilizator amaliarebAmalia Rebegea amaliareb Data 7 martie 2018 20:20:20
Problema Secventa 5 Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <bits/stdc++.h>
#define unt unsigned int

using namespace std;
ifstream f("secv5.in");
ofstream g("secv5.out");
const int MaxN = 1048580, mod = 666013;
unt n, v[MaxN], lft[MaxN], rgt[MaxN], mini, maxi;

struct HASH {
    unt ind = 0, start[mod], urm[MaxN], val[MaxN], fr[MaxN];
    HASH() {
        memset(start, 0, sizeof start);
        memset(urm, 0, sizeof urm);
        memset(val, 0, sizeof val);
        memset(fr, 0, sizeof fr);
    }

    int Find(unt x) {
        int poz = start[x % mod];
        while (poz && val[poz] != x) poz = urm[poz];
        return poz;
    }

    void Add(unt x) {
        val[++ind] = x;
        urm[ind] = start[x % mod];
        start[x % mod] = ind;
        fr[ind] = 1;
    }

    void Del(unt x) {
        int poz = start[x % mod];
        if (val[poz] == x) {
            --fr[poz];
            if (fr[poz] == 0) start[x % mod] = urm[poz];
            return;
        }
        while (urm[poz] && val[urm[poz]] != x) poz = urm[poz];
        if (val[urm[poz]] == x) {
            --fr[urm[poz]];
            if (fr[urm[poz]] == 0) urm[poz] = urm[urm[poz]];
        }
    }

    void Clear() {
        memset(start, 0, sizeof start);
        memset(urm, 0, sizeof urm);
        memset(val, 0, sizeof val);
        memset(fr, 0, sizeof fr);
        ind = 0;
    }
} H;


int main()
{
    f >> n >> mini >> maxi;
    for (int i = 1; i <= n; ++i) f >> v[i];
    int st = 1, nr = 0;
    for (int i = 1; i <= n; ++i) {
        if (H.Find(v[i])) H.fr[H.Find(v[i])]++;
        else ++nr, H.Add(v[i]);
        while (nr >= mini && st < i) {
            H.Del(v[st]);
            if (!H.Find(v[st])) --nr;
            ++st;
        }
        if (nr < mini && st > 1) {
            --st;
            if(H.Find(v[st])) H.fr[H.Find(v[st])]++;
            else ++nr, H.Add(v[st]);
        }
        if (nr >= mini) rgt[i] = st;
    }
    H.Clear();
    st = 1, nr = 0;
    for (int i = 1; i <= n; ++i) {
        if (H.Find(v[i])) H.fr[H.Find(v[i])]++;
        else ++nr, H.Add(v[i]);
        while (nr > maxi && st < i) {
            H.Del(v[st]);
            if (!H.Find(v[st])) --nr;
            ++st;
        }
        lft[i] = st;
    }
    unsigned long long ans = 0;
    for (int i = 1; i <= n; ++i) if (rgt[i] >= lft[i]) ans += rgt[i] - lft[i] + 1;
    g << ans << '\n';
    return 0;
}