Cod sursa(job #10185)

Utilizator astronomyAirinei Adrian astronomy Data 27 ianuarie 2007 23:06:27
Problema Secventa 5 Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 2.93 kb
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_N ((1 << 20)+16)
#define MOD (1 << 18)

typedef long long llong;

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

unsigned X[MAX_N];

llong res;

unsigned V[MOD][20], Ind[MOD][20];

void preproc(void)
{
    int i, j, key, ind = 0;
    unsigned t;
    
    for(i = 1; i <= N; i++)
    {
        key = (t = X[i]) & (MOD-1);
        for(j = 1; j <= V[key][0]; j++)
         if(V[key][j] == t)
         {
            X[i] = Ind[key][j];
            break ;
         }
        if(j == V[key][0]+1)
        {
            ind++;
            V[key][++V[key][0]] = t;
            Ind[key][V[key][0]] = ind;
            X[i] = 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;
}