Cod sursa(job #483166)

Utilizator Addy.Adrian Draghici Addy. Data 7 septembrie 2010 09:51:48
Problema Secventa 5 Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <cstdio>
#include <vector>

using namespace std;

const int NMAX = 1050000;
const int MOD = 997037;

struct nod {
	unsigned int v; int nr;
	nod *next;
} *HASH1[MOD + 50], *HASH2[MOD + 50];

unsigned int A[NMAX];
int MIN[NMAX], MAX[NMAX], n, dmin, dmax, d;

void citire (), calcul (), adauga (nod*&, unsigned int), sterge (nod*&, unsigned int), afisare ();

int main () {
	
	citire ();
	
	calcul ();
	
	afisare ();
	
	return 0;
}

void citire () {
	
	freopen ("secv5.in", "r", stdin);
	
	char aux[32];
	int i, j;
	unsigned int x;
	
	scanf ("%d %d %d\n", &n, &dmin, &dmax);
	
	for (i = 1; i <= n; i++) {
		scanf ("%s", aux);
		for (j = 0, x = 0; aux[j] >= '0' && aux[j] <= '9'; j++)
			x = x * 10 + (aux[j] - '0');
		A[i] = x;
	}
}

void calcul () {
	
	int p, u;
	
	p = 1, u = 0;
	
	while (p <= n && u < n) {
		u++;
		adauga (HASH1[A[u] % MOD], A[u]);
		
		while (d > dmax) {
			sterge (HASH1[A[p] % MOD], A[p]);
			p++;
		}
		
		MAX[u] = p;
	}
	
	p = n, u = n, d = 0;
	
	while (p >= 0 && u > 0) {
		
		if (p == 0 && d >= dmin)
			MIN[u] = 1;
		else if (p == 0)
			break;
		
		while (d < dmin) {
			adauga (HASH2[A[p] % MOD], A[p]);
			p--;
		}
		
		MIN[u] = p + 1;
		
		sterge (HASH2[A[u] % MOD], A[u]);
		u--;
	}
}

void adauga (nod *&H, unsigned int x) {
	
	nod *p;
	
	for (p = H; p != NULL; p = p -> next)
		if (p -> v == x) {
			p -> nr++;
			return;
		}
	
	p = new nod; d++;
	p -> v = x, p -> nr = 1, p -> next = H;
	H = p;
}

void sterge (nod *&H, unsigned int x) {
	
	nod *p, *aux;
	
	for (p = H; p != NULL; p = p -> next)
		if (p -> v == x) {
			p -> nr--;
			
			if (p -> nr == 0) {
				if (p == H) {
					aux = H, H = H -> next;
					delete aux;
				}
				else {
					aux = p, p = p -> next;
					delete aux;
				}
				
				d--;
			}
			
			return;
		}
}

void afisare () {
	
	freopen ("secv5.out", "w", stdout);
	
	int i; long long sol = 0;
	
	for (i = 1; i <= n; i++)
		if (MIN[i] >= MAX[i] && MIN[i] > 0)
			sol += MIN[i] - MAX[i] + 1;
	
	printf ("%lld", sol);
}