Cod sursa(job #360290)

Utilizator katakunaCazacu Alexandru katakuna Data 30 octombrie 2009 20:45:18
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <cstdio>
#include <algorithm>
using namespace std;

#define Nmax 17010

struct suffix {int a, b, p;} L[Nmax];
int N, k, K, i, n, sol, aux, Min, j;
int P[16][Nmax], p[Nmax], H[Nmax], poz[Nmax], pre[Nmax];
char s[Nmax];

int cmp (const suffix &x, const suffix &y) {
	if (x.a == y.a) return x.b < y.b;
	return x.a < y.a;
}

int cmp2 (int x, int y) {
	if (P[k][x] == P[k][y]) return x > y;
	return P[k][x] < P[k][y];
}

void suffix_arrays () {

	int i, pp, nr = 0;
	for (i = 0; i < N; i++)
		P[0][i] = s[i];
	
	for (k = 1; (1 << k) < N; k++) {
		pp = (1 << (k-1));
		for (i = 0; i < N; i++) {
			L[i].a = P[k-1][i];
			if ( (i + pp) < N ) L[i].b = P[k-1][i + pp];
			else L[i].b = -1;
			L[i].p = i;
		}
		
		sort (L, L + N, cmp);
		nr = 0; P[k][L[0].p] = nr;
		for (i = 1; i < N; i++) 
			if ( L[i].a == L[i - 1].a && L[i].b == L[i - 1].b ) P[k][ L[i].p ] = nr;
			else P[k][ L[i].p ] = ++nr;
		
		
	}

}

int lcp (int x, int y) {

	int i, len = 0;;
	for (i = k; i >= 0 && x < N && y < N; i--) 
		if (P[i][x] == P[i][y])
			len+= (1 << i), x+= (1 << i), y+= (1 << i);
	
	return len;
}

void add_heap (int x) {
	
	H[++n] = x; poz[x] = n;
	int fiu = n, tata = n >> 1;
	while ( pre[H[fiu]] < pre[H[tata]] && tata >= 1 ) {
		aux = H[fiu];
		H[fiu] = H[tata];
		H[tata] = aux;
		
		poz[H[fiu]] = fiu;
		poz[H[tata]] = tata;
		
		fiu = tata;
		tata = fiu >> 1;
	}
}

void del_heap (int x) {
	
	H[poz[x]] = H[n]; poz[H[poz[x]]] = poz[x]; n--;
	
	int tata = poz[x], fiu; fiu = tata << 1;
	if ( pre[H[fiu + 1]] < pre[H[fiu]] && fiu < n ) fiu++;
	
	while ( pre[H[tata]] > pre[H[fiu]]  && fiu <= n ) {
		aux = H[fiu];
		H[fiu] = H[tata];
		H[tata] = aux;
		
		poz[H[fiu]] = fiu;
		poz[H[tata]] = tata;
		
		tata = fiu;
		fiu = tata << 1;
		if ( pre[H[fiu + 1]] > pre[H[fiu]] && fiu < n ) fiu++;
	}
	
}

int main () {

	FILE *f = fopen ("substr.in", "r");
	FILE *g = fopen ("substr.out", "w");

	fscanf (f, "%d %d\n", &N, &K);
	for (i = 0; i < N; i++)
		fscanf (f, "%c", &s[i]);
	
	suffix_arrays (); k--;
	
	for (i = 0; i < N; i++)
		p[i] = i;
	
	sort (p, p + N, cmp2);
	
	/*for (i = 0; i < N; i++) {
		for (j = p[i]; j < N; j++)
			printf ("%c", s[j]);
		
		printf ("\n");
	}*/
	
	//K--;
	for (i = 1; i < K; i++) {
		pre[i] = lcp(p[i], p[i-1]);
		//add_heap (i);
	}
	
	for (i = K; i < N; i++) {
		pre[i] = lcp(p[i], p[i-1]);
		//add_heap (i);
		//sol = max (sol, pre[H[1]]);
		//del_heap (i-K+1);
	}
	
	//K++;
	//if (K == 1) sol = N;
	//fprintf (g, "%d\n", sol);
	
	//for (i = 1; i < N; i++)
		//fprintf (g, "%d ", pre[i]);
	
	
	sol = 0;
	for (i = K-1; i < N; i++) {
		Min = 1 << 30;
		for (j = i; j >= i - K+2; j--)
			Min = min(Min, pre[j]);
		
		sol = max (sol , Min);
	}
	
	if (K == 1) sol = N;
	fprintf (g, "%d", sol);
	
	
	fclose (f);
	fclose (g);
	
	return 0;

}