Cod sursa(job #10326)

Utilizator astronomyAirinei Adrian astronomy Data 28 ianuarie 2007 12:01:40
Problema Secventa 5 Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_N ((1 << 20)+16)
#define MOD_1 100003
#define MOD_2 100019

typedef long long llong;

int N, U, L, Nr_unu[MAX_N], Nr_doi[MAX_N];

unsigned X[MAX_N];

llong res;

unsigned V1[MOD_1][4], Ind1[MOD_1][4];
unsigned V2[MOD_2][4], Ind2[MOD_2][4];

void preproc(void)
{
    int i, j, ok, key1, key2, ind = 0;
    unsigned t;
    
    for(i = 1; i <= N; i++)
    {
        key1 = (t = X[i]) % MOD_1;
        key2 = (t = X[i]) % MOD_2;

        ok = 0;
        
        for(j = 1; j <= V1[key1][0]; j++)
         if(V1[key1][j] == t)
         {
            ok = 1;
            X[i] = Ind1[key1][j];
            break ;
         }
         
        if(ok == 1)
            continue ;

        for(j = 1; j <= V2[key2][0]; j++)
         if(V2[key2][j] == t)
         {
            ok = 1;
            X[i] = Ind2[key2][j];
            break ;
         }

        if(ok == 1)
            continue ;

        ind++;
        
        if(V1[key1][0] <= V2[key2][0])
        {
            V1[key1][++V1[key1][0]] = X[i];
            X[i] = ind;
            Ind1[key1][V1[key1][0]] = ind;
        }
        else
        {
            V2[key2][++V2[key2][0]] = X[i];
            X[i] = ind;
            Ind2[key2][V2[key2][0]] = ind;
        }
    }
}
    
void solve(void)
{
    int i, p, q, t, aux, cnt_unu = 0, cnt_doi;
    unsigned x, v;

    preproc();

    p = q = 1, cnt_unu = cnt_doi = 1, t = X[1];
    Nr_unu[t]++, Nr_doi[t]++;

    if(L == 1)
        res++;

    for(i = 2; i <= N; i++)
    {
        t = aux = X[i];
        if(Nr_unu[t] == 0)
        {
            cnt_unu++;
            Nr_unu[t]++;
            if(cnt_unu == L)
            {
                while( Nr_unu[t = X[p]] >= 2 )
                    Nr_unu[t]--, p++;
            }
            if(cnt_unu > L)
            {
                while(p < i)
                {
                    Nr_unu[t = X[p++]]--;
                    if(Nr_unu[t] == 0)
                        break ;
                }
                while( Nr_unu[t = X[p]] >= 2 )
                    Nr_unu[t]--, p++;
            }
        }
        else
        {
            Nr_unu[t]++;
            if(cnt_unu >= L)
                while( Nr_unu[t = X[p]] >= 2 )
                    Nr_unu[t]--, p++;
        }
        t = aux;
        if(Nr_doi[t] == 0)
        {
            cnt_doi++;
            Nr_doi[t]++;
            if(cnt_doi > U)
            {
                while(q < i)
                {
                    Nr_doi[t = X[q++]]--;
                    if(Nr_doi[t] == 0)
                        break ;
                }
            }
        }
        else
            Nr_doi[t]++;

        if(cnt_unu >= L)
            res += (llong)(p-q+1);
    }
}

void read_data(void)
{
    int i, ind;
    unsigned x;
    char sir[1024];
    
    scanf("%d %d %d\n", &N, &L, &U);

    for(i = 1; i <= N; i++)
    {
        fgets(sir, 1024, stdin), ind = 0, x = 0;
        for(; sir[ind] >= '0' && sir[ind] <= '9'; ind++)
            x = x*10+(sir[ind]-48);
        X[i] = x;
    }
}

void write_data(void)
{
    printf("%lld\n", res);
}

int main(void)
{
    freopen("secv5.in", "rt", stdin);
    freopen("secv5.out", "wt", stdout);

    int start = clock(), end;
    
    read_data();
    solve();
    write_data();

    end = clock();

    fprintf(stderr, "%lf\n", (double)(end-start) / CLK_TCK);

    return 0;
}