Cod sursa(job #2155656)

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

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

struct HASH {
    long long 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);
    }

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

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

    void Del(long long x) {
        long long poz = start[x % mod];
        if (val[poz] == x) {
            --fr[poz];
            return;
        }
        while (urm[poz] && val[urm[poz]] != x) poz = urm[poz];
        if (val[urm[poz]] == x) {
            --fr[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];
    long long st = 1, nr = 0;
    for (int i = 1; i <= n; ++i) {
        if (H.Find(v[i])) {
            H.fr[H.Find(v[i])]++;
            if (H.fr[H.Find(v[i])] == 1) ++nr;
        }
        else ++nr, H.Add(v[i]);
        while (nr >= mini && st < i) {
            H.Del(v[st]);
            if (!H.fr[H.Find(v[st])]) --nr;
            ++st;
        }
        while (nr < mini && st > 1) {
            --st;
            if(H.Find(v[st])) {
                H.fr[H.Find(v[st])]++;
                if (H.fr[H.Find(v[st])] == 1) ++nr;
            }
            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])]++;
            if (H.fr[H.Find(v[i])] == 1) ++nr;
        }
        else ++nr, H.Add(v[i]);
        while (nr > maxi && st < i) {
            H.Del(v[st]);
            if (!H.fr[H.Find(v[st])]) --nr;
            ++st;
        }
        lft[i] = st;
    }
    long long ans = 0;
    for (int i = 1; i <= n; ++i) if (rgt[i] >= lft[i]) ans += 1LL * rgt[i] - lft[i] + 1;
    g << ans << '\n';
    return 0;
}