Cod sursa(job #1818916)

Utilizator silkMarin Dragos silk Data 29 noiembrie 2016 22:37:15
Problema Secventa 5 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.91 kb
#include <cstdio>
#include <vector>
#define NMax 1000000
#define uint unsigned int
using namespace std;

const int P = 147481;

vector<int> h[P];
vector<int> g[P];
uint v[NMax+1];
int f[2][NMax+1];
int N,L,U,temp;

void Add(uint x)
{
    int r = x%P;
    for(int i = 0; i < h[r].size(); ++i)
    if( h[r][i] == x )
    {
        ++g[r][i];
        return;
    }
    h[r].push_back(x);
    g[r].push_back(1);
    ++temp;
}

void Erase(uint x)
{
    int r = x%P;
    int L = h[r].size()-1;
    for(int i = 0; i < h[r].size(); ++i)
    if( h[r][i] == x )
    {
        --g[r][i];
        if( !g[r][i] )
        {
            g[r][i] = g[r][L]; h[r][i] = h[r][L];
            g[r].pop_back(); h[r].pop_back();
            --temp;
        }
        return;
    }
}

void Clear()
{
    for(int i = 0; i < P; ++i)
    while( !h[i].empty() ) { h[i].pop_back(); g[i].pop_back(); }
}

void Solve(int K, int l)
{
    int i,pos;
    temp = 0;
    for(i = 1; i <= N; ++i)
    {
        Add(v[i]);
        if(temp==K) break;
    }
    pos = i;
    if(pos>N) return;

    while(temp==K && pos < N && l) Add(v[++pos]);
    if(temp>K && l) Erase(v[pos--]);
    f[l][1] = pos;

    for(i = 2; i <= N; ++i)
    {
        Erase(v[i-1]);
        while( temp < K && pos < N ) Add(v[++pos]);
        if( temp < K ) return;

        while(temp==K && pos < N && l) Add(v[++pos]);
        if(temp>K && l) Erase(v[pos--]);
        f[l][i] = pos;
    }
}

int main(){
    freopen("secv5.in","r",stdin);
    freopen("secv5.out","w",stdout);

    int i;
    long long ans = 0;

    scanf("%d %d %d",&N,&L,&U);
    for(i = 1; i <= N; ++i) scanf("%llu",&v[i]);

    Solve(L,0);
    Clear();
    Solve(U,1);

    for(i = 1; i <= N; ++i)
    if( f[0][i] )
    {
        if( !f[1][i] ) f[1][i] = N;
        ans += f[1][i] - f[0][i] + 1;
    }

    printf("%lld\n",ans);



return 0;
}