Cod sursa(job #10172)

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

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

typedef long long llong;

int N, U, L, Ind;
unsigned *H1[MOD], *H2[MOD], *Nr1[MOD], *Nr2[MOD], deg[MOD];

unsigned X[MAX_N];

int V[MAX_N];

llong res;

void baga(unsigned x, int key, int type)
{
    int i;
    unsigned *p, *c;
    if(type == 0)
    {
        for(p = H1[key], c = Nr1[key], i = deg[key]; i >= 0; i--, p++, c++)
         if(*p == x)
         {
            (*c)++;
            break ;
         }
        if(i == deg[key])
        {
            for(p = H1[key], c = Nr1[key], i = deg[key]; i >= 0; i--, p++, c++)
             if(*p == 0)
             {
                *p = x, *c = 1;
                break ;
             }
        }
    }
    else
    {
        for(p = H2[key], c = Nr2[key], i = deg[key]; i >= 0; i--, p++, c++)
         if(*p == x)
         {
            (*c)++;
            break ;
         }
        if(i == deg[key])
        {
            for(p = H2[key], c = Nr2[key], i = deg[key]; i >= 0; i--, p++, c++)
             if(*p == 0)
             {
                *p = x, *c = 1;
                break ;
             }
        }
    }
}

int count(unsigned x, int key, int type)
{
    int i;
    unsigned *p, *c;
    if(type == 0)
    {
        for(p = H1[key], c = Nr1[key], i = deg[key]; i >= 0; i--, p++, c++)
         if(*p == x)
            return *c;
        return 0;
    }
    if(type == 1)
    {
        for(p = H2[key], c = Nr2[key], i = deg[key]; i >= 0; i--, p++, c++)
         if(*p == x)
            return *c;
        return 0;
    }
}

void scoate(unsigned x, int key, int type)
{
    int i;
    unsigned *p, *c;
    if(type == 0)
    {
        for(p = H1[key], c = Nr1[key], i = deg[key]; i >= 0; i--, p++, c++)
         if(*p == x)
         {
            (*c)--;
            if(*c == 0)
                *p = 0;
            break ;
         }
    }
    if(type == 1)
    {
        for(p = H2[key], c = Nr2[key], i = deg[key]; i >= 0; i--, p++, c++)
         if(*p == x)
         {
            (*c)--;
            if(*c == 0)
                *p = 0;
            break ;
         }
    }
}

void solve(void)
{
    int i, p, q, t, aux, cnt_unu, cnt_doi;
    unsigned x, v;

    p = q = 1, cnt_unu = cnt_doi = 1;

    baga(X[1], V[1], 1);
    baga(X[1], V[1], 0);
    
    if(L == 1)
        res++;

    for(i = 2; i <= N; i++)
    {
        x = X[i], v = V[i];

        if( count(x, v, 0) == 0)
        {
            cnt_unu++;
            baga(x, v, 0);
            if(cnt_unu == L)
            {
                while( count(X[p], V[p], 0) >= 2 )
                    scoate(X[p], V[p], 0), p++;
            }
            if(cnt_unu > L)
            {
                while(p < i)
                {
                    scoate(X[p], V[p], 0), p++;
                    if(count(X[p-1], V[p-1], 0) == 0)
                        break ;
                }
                while( count(X[p], V[p], 0) >= 2 )
                    scoate(X[p], V[p], 0), p++;
            }
        }
        else
        {
            baga(x, v, 0);
            if(cnt_unu >= L)
                while( count(X[p], V[p], 0) >= 2 )
                    scoate(X[p], V[p], 0), p++;
        }
        if( count(x, v, 1) == 0)
        {
            cnt_doi++;
            baga(x, v, 1);
            if(cnt_doi > U)
            {
                while(q < i)
                {
                    scoate(X[q], V[q], 1), q++;
                    if(count(X[q-1], V[q-1], 1) == 0)
                        break ;
                }
            }
        }
        else
            baga(x, v, 1);

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

unsigned viz[MOD][16];

int cauta(unsigned x, int key)
{
    int i;
    for(i = 1; i <= viz[key][0]; i++)
     if(viz[key][i] == x)
        return 1;
    return 0;
}

void adauga(unsigned x, int key)
{
    viz[key][0]++;
    viz[key][viz[key][0]] = x;
}

void read_data(void)
{
    int i, j, ind;
    unsigned x;
    char sir[1024];

    int maxx = 0;
    
    
    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+(unsigned)(sir[ind]-48);
        X[i] = x, V[i] = x % MOD;
        if( !cauta(x, V[i]) )
            adauga(x, V[i]), deg[V[i]]++;
    }

    for(i = 0; i < MOD; i++)
     if(viz[i][0] > maxx)
        maxx = viz[i][0];

    for(i = 0; i < MOD; i++)
     if(deg[i] > 0)
     {
        H1[i] = (unsigned*) malloc(sizeof(unsigned)*(deg[i]+2));
        H2[i] = (unsigned*) malloc(sizeof(unsigned)*(deg[i]+2));
        Nr1[i] = (unsigned*) malloc(sizeof(unsigned)*(deg[i]+2));
        Nr2[i] = (unsigned*) malloc(sizeof(unsigned)*(deg[i]+2));
        for(j = 0; j < deg[i]; j++)
            H1[i][j] = H2[i][j] = 0;
     }
}

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;
}