Cod sursa(job #350598)

Utilizator slayerdmeMihai Dumitrescu slayerdme Data 24 septembrie 2009 22:53:27
Problema Divk Scor 50
Compilator c Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <stdio.h>
#include <stdlib.h>

#define NMAX 500000
#define KMAX 100000

int main()
{
    int n, a, b, k;
    int i, j, x, sum;
    int sums[NMAX + 1];
    int repeats[KMAX];
    int repeatsum[KMAX];
    int allpositions[NMAX + 1];

    int *positions;

    FILE *fin;
    FILE *fout;


    fin = fopen("divk.in", "r");
    fout = fopen("divk.out", "w");
    fscanf(fin, "%d", &n);
    fscanf(fin, "%d", &k);
    fscanf(fin, "%d", &a);
    fscanf(fin, "%d", &b);

    sum = 0;
    for (i = 0; i < n; i++) {
        fscanf(fin, "%d", &x);
        sums[i] = sum;
        repeats[sum]++;
        sum += x;
        sum = sum % k;
    }
    sums[n] = sum;
    repeats[sum]++;

    fclose(fin);

    sum = 0;
    for (i = 0; i < k; i++) {
        repeatsum[i] = sum;
        sum += repeats[i];
    }

    //debug
    printf("%d\n", lognsearch(repeatsum, k, 3, 0));
    for (i = 0; i < k; i ++) {
        printf("%d\n", repeatsum[i]);
    }
    printf("end repeatsum\n");
    //enddebug

    for (i = 0; i <= n; i++) {
        allpositions[repeatsum[sums[i]]] = i;
        repeatsum[sums[i]]++;
    }

    //debug
    for (i = 0; i <= n; i++) {
        printf("%d\n", sums[i]);
    }
    printf("end sums\n");
    for (i = 0; i <= n; i ++) {
        printf("%d\n", allpositions[i]);
    }
    printf("end allpositions\n");
    //enddebug

    sum = 0;
    for (i = 0; i < k; i++) {
        repeatsum[i] = sum;
        sum += repeats[i];
    }
    int divk = 0;
    int asearch, bsearch;
    int t;
    for (i = 0; i < k; i++)
        if (repeats[i] > 1) {
            j = repeats[i];
            positions = allpositions + repeatsum[i];
            printf("%d ", i);
            printf("%d next\n", repeats[i]);
            for (t = 0; t < j; t++) {
                printf("%d ", positions[t]);
            }
            printf("blah\n");
            for (t = 0; t < j - 1; t++) {
                asearch = lognsearch(positions, repeats[i], t, positions[t] + a);
                bsearch = lognsearch(positions, repeats[i], t, positions[t] + b + 1);
                printf("search %d %d %d %d\n", repeats[i], t, positions[t] + a, positions[t] + b);
                printf("searchk %d %d %d\n", asearch, bsearch, divk);
                divk += bsearch - asearch;
            }
        }
    fprintf(fout, "%d\n", divk);
    return 0;
}

/** Returns the position of the smallest entry larger or equal to query after pos in an ordered array. Return length if none found
/** Pos has to be >= 0. Array entries should not repeat. **/
int lognsearch(int *array, int lenght, int pos, int query) {
    int i = pos, multi = 1;
    while (i < lenght && array[i] < query) {
        if (i + multi < lenght && array[i + multi] < query) {
            i = i + multi;
            multi = multi * 2;
        } else if (multi > 1) {
            multi = multi / 2;
        } else {
            i++;
            break;
        }
    }
    return i;
}