Cod sursa(job #9572)

Utilizator flachiFlorin Asavoaie flachi Data 27 ianuarie 2007 16:14:08
Problema Secventa 5 Scor 0
Compilator c Status done
Runda Unirea 2007, clasele 11-12 Marime 1.45 kb
#include <stdio.h>
#include <stdlib.h>

void cit (void);
int cmp (const void *, const void *);
unsigned poz (unsigned, unsigned, unsigned);

typedef struct {
    unsigned val;
    unsigned poz;
} camp;

camp a[1<<20];
camp s[1<<20];

unsigned n, u, l;

int main () {
unsigned i, j, dist = 0, count = 0;
FILE * out;
    cit ();
    qsort (s, n, sizeof (camp), cmp);
    for (i=0; i<n-l+1; i += (dist > u ? 0 : 1)) {
	for (j=0; dist <= u && i+j < n; j++) {
	    if (poz (a[j+i].val, i, i+j ? 0 : i+j-1) == j+i)
		dist++;
	    if (dist >= l && dist <= u)
		count++;
	}
	if (poz (a[i].val, i+1, i+j) == (unsigned) -1)
	    dist--;
    }
    out = fopen ("secv5.out", "w");
    fprintf (out, "%u\n", count);
    fclose (out);
    return 0;
}

unsigned poz (unsigned val, unsigned i, unsigned j) {
unsigned st = 0, dr = n, x = (st + dr) / 2;
    while (s[x].val != val && st < dr) {
	if (s[x].val > val)
	    dr = x;
	else
	    st = x;
	x = (st + dr) / 2;
    }
    if (val != s[x].val)
	return (unsigned) -1;
    while (s[x-1].val == val)
	x--;
    for (; s[x].val == val; x++)
	if (s[x].poz >= i && s[x].poz <= j)
	    return s[x].poz;
    return (unsigned) -1;
}

int cmp (const void * a, const void * b) {
    return ((camp *) a)->val - ((camp *) b)->val;
}

void cit (void) {
FILE * in;
unsigned i;
    in = fopen ("secv5.in", "r");
    fscanf (in, "%u %u %u", &n, &l, &u);
    for (i=0; i<n; i++) {
	fscanf (in, "%u", &a[i].val);
	a[i].poz = i;
	s[i] = a[i];
    }
    fclose (in);
}