Cod sursa(job #198057)

Utilizator DastasIonescu Vlad Dastas Data 8 iulie 2008 11:47:01
Problema Divk Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.46 kb
#include <cstdio>
#include <cstdlib>

const int maxn = 500001;
const int maxk = 100001;

FILE *in = fopen("divk.in","r"), *out = fopen("divk.out","w");

int n, k, a, b;

int s[maxn];
int nr[maxk];
int *list[maxk];
int cnt[maxk];

void read()
{
    fscanf(in, "%d %d %d %d", &n, &k, &a, &b);

    int x = 0;
    for ( int i = 1; i <= n; ++i )
    {
        fscanf(in, "%d", &x);

        s[i] = (s[i-1] + x) % k;

        ++nr[ s[i] ];
    }

    for ( int i = 0; i < k; ++i )
        list[i] = (int *)calloc(nr[i] + 2, sizeof(int));

    for ( int i = 0; i <= n; ++i )
        list[ s[i] ][ ++cnt[ s[i] ] ] = i;
}

int go(int len)
{
    int answ = 0;

    for ( int i = 0; i < k; ++i )
    {
        if ( cnt[i] == 1 )
            continue;

        int start = 1;
        int end = 2;

        int here = 0;
        while ( start < end && end <= cnt[i] )
        {
            while ( list[i][end] - list[i][start] <= len && end <= cnt[i] )
                ++answ, ++here, ++end;

            ++start;

            if ( end > cnt[i] )
                --end;
        }

//        list[i][0] = 1;
//        printf("rest %d: ", i);
//        while ( list[i][0] <= cnt[i] )
//        {
//            printf("%d, ", list[i][ list[i][0] ]);
//
//            ++list[i][0];
//        }
//        printf("\n");
    }

    return answ;
}

int main()
{
    read();

    fprintf(out, "%d\n", go(b) - go(a-1));

    return 0;
}