Cod sursa(job #798425)

Utilizator GrimpowRadu Andrei Grimpow Data 16 octombrie 2012 17:01:21
Problema Secventa 5 Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 kb
#include <cstdio>
#include <vector>

#define NMax 1050000
#define U 666013
#define x first
#define n second
#define Buff 20000001

using namespace std;

vector < pair <unsigned, int> > H[U];
int N, NDistinct, L[2], Limit[2][NMax], BuffI;
unsigned V[NMax];
long long S;
char Buffer[Buff];

inline unsigned ReadX()
{
    unsigned X=0;
    while(!(Buffer[BuffI]>='0' && Buffer[BuffI]<='9'))
    {
        ++BuffI;
    }
    while(Buffer[BuffI]>='0' && Buffer[BuffI]<='9')
    {
        X=X*10+Buffer[BuffI]-'0';
        ++BuffI;
    }
    return X;
}

inline void Insert (unsigned X)
{
    int Key=X%U;
    for (unsigned i=0; i<H[Key].size (); ++i)
    {
        if (H[Key][i].x==X)
        {
            ++H[Key][i].n;
            return;
        }
    }
    ++NDistinct;
    H[Key].push_back (make_pair (X, 1));
}

inline void Delete (unsigned X)
{
    int Key=X%U;
    for (vector < pair <unsigned, int> > :: iterator i=H[Key].begin (); i!=H[Key].end (); ++i)
    {
        if ((*i).x==X)
        {
            --(*i).n;
            if ((*i).n==0)
            {
                --NDistinct;
                H[Key].erase (i);
            }
            return;
        }
    }
}

void Read ()
{
    freopen ("secv5.in", "r", stdin);
    fread (Buffer, 1, Buff, stdin);
    N=(int)ReadX ();
    L[0]=(int)ReadX ();
    L[1]=(int)ReadX ();
    --L[0];
    for (int i=1; i<=N; ++i)
    {
        V[i]=ReadX ();
    }
}

void Print ()
{
    freopen ("secv5.out", "w", stdout);
    printf ("%lld\n", S);
}

void SolveL (int K)
{
    Limit[K][0]=1;
    for (int i=1; i<=N; ++i)
    {
        Limit[K][i]=Limit[K][i-1];
        Insert (V[i]);
        while (NDistinct>L[K])
        {
            Delete (V[Limit[K][i]]);
            ++Limit[K][i];
        }
        if (K==0)
        {
            S-=(i-Limit[K][i]+1);
        }
        else
        {
            S+=(i-Limit[K][i]+1);
        }
    }
    int Left=Limit[K][N];
    while (Left<=N)
    {
        Delete (V[Left]);
        ++Left;
    }
}

int main()
{
    Read ();
    SolveL (0);
    SolveL (1);
    Print ();
    return 0;
}