Cod sursa(job #198126)

Utilizator DastasIonescu Vlad Dastas Data 8 iulie 2008 18:11:31
Problema Divk Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.68 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, end = cnt[i];

        while ( list[i][end] - list[i][start] > len )
            ++start;

        int t = end - start + 1;
        answ = answ + t*(t-1)/2;

        for ( --start; start; --start )
        {
            //int ok = 0;
            while ( list[i][end] - list[i][start] > len && end > start )
                --end;//, ok = 1;

//            if ( ok )
//                ++end;

            t = end - start + 1;
            answ = answ + t*(t-1)/2;
        }

//        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(stdout, "%d\n%d\n", go(b), go(a-1));
    fprintf(out, "%d\n", go(b) - go(a-1));

    return 0;
}