Cod sursa(job #1564162)

Utilizator dnprxDan Pracsiu dnprx Data 8 ianuarie 2016 19:23:17
Problema Secventa 5 Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <bits/stdc++.h>
#define P 710119

using namespace std;

struct pereche
{
    int val, nrap;
};

vector <pereche> h[P+1];
int a[(1 << 20) + 5], n, L, U;

void Citire()
{
    int i;
    ifstream fin("secv5.in");
    fin >> n >> L >> U;
    for (i = 1; i <= n; ++i)
        fin >> a[i];
    fin.close();
}

/// cauta in hash valoarea elem
inline int Cauta(int elem)
{
    int r;
    unsigned j;
    r = elem % P;
    for (j = 0; j < h[r].size(); ++j)
        if (h[r][j].val == elem) return j;
    return -1;
}

/// sterge elementul elem care stiu ca se afla
/// la pozitia poz in hash[elem%P]
inline void Sterge(int elem, int poz)
{
    int r;
    unsigned j;
    r = elem % P;
    j = h[r].size();
    if (h[r][poz].nrap > 1) h[r][poz].nrap--;
    else
    {
        h[r][poz] = h[r][j - 1];
        h[r].pop_back();
    }
}

inline void Inserare(int elem, int poz)
{
    int r;
    pereche e;
    r = elem % P;
    if (poz == -1)
    {
        e.val = elem;
        e.nrap = 1;
        h[r].push_back(e);
    }
    else h[r][poz].nrap++;
}

/// numarul secventelor de lungime <= X
long long NrSecv(int X)
{
    int i, j, cnt, v, poz;
    long long nrSecv;
    /// golesc hash-ul
    for (i = 0; i < P; ++i)
    {
        v = h[i].size();
        while (v > 0)
        {
            h[i][0] = h[i][v - 1];
            h[i].pop_back();
            v--;
        }
    }
    ///--------------
    j = 1;
    cnt = 0; /// numarul de valori distincte din hash
    nrSecv = 0;
    for (i = 1; i <= n; ++i)
    {
        v = a[i];
        /// caut daca apare a[i] in hash
        poz = Cauta(v);
        if (poz == -1) cnt++;
        Inserare(v, poz);
        while (cnt > X) /// scot din multiset
        {
            poz = Cauta(a[j]);
            Sterge(a[j], poz);
            poz = Cauta(a[j]);
            if (poz == -1) cnt--;
            j++;
        }
        nrSecv += (i - j + 1);
    }
    return nrSecv;
}

void Afisare()
{
    long long rez;
    rez = NrSecv(U) - NrSecv(L - 1);
    ofstream fout("secv5.out");
    fout << rez << "\n";
    fout.close();
}

int main()
{
    Citire();
    Afisare();
    return 0;
}