Cod sursa(job #1014380)

Utilizator roots4Irimia Alexandru Gabriel roots4 Data 22 octombrie 2013 16:38:15
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.58 kb
#include<fstream>
#include<algorithm>
#include<string.h>

using namespace std;

#define max_n 51000

ifstream f("ghicit.in");
ofstream g("ghicit.out");

char S[max_n];
int L , i , j , stp , cnt , nr , sol;
int P[20][max_n];

struct z{
	int i , p;
}Z[max_n];

struct entry{
	int p;
	int nr[2];
}V[max_n];

bool cmp( entry a , entry b ){
	return a.nr[0] == b.nr[0] ? a.nr[1] < b.nr[1] : a.nr[0] < b.nr[0];
}

bool cmp1( z a , z b ){
	return a.i < b.i;
}

int lcp( int a , int b ){
	
	int sol = 0;
	
	if( a == b )
		return L - a;
	
	for( int i = stp ; i >= 0 && a < L && b < L ; i-- ){
		if( P[i][a] == P[i][b] ){
			a += (1<<i);
			b += (1<<i);
			sol += (1<<i);
		}
	}
	
	return sol;	
}

int main(){
	
	f>>S; L = strlen(S);
	
	for( i = 0 ; i < L ; i++ )
		Z[i].i = (int)S[i] , Z[i].p = i;
	
	sort(Z , Z+L , cmp1); nr = 0;
	
	for( i = 0 ; i < L ; i++ )
		P[0][Z[i].p] = i > 0 && Z[i].i == Z[i-1].i ? P[0][Z[i-1].p] : (nr++);
	
	for( stp = 1 , cnt = 1 ; (cnt>>1) < L ; stp++ , cnt *= 2 ){
		
		for( i = 0 ; i < L ; i++ ){
			V[i].p = i;
			V[i].nr[0] = P[stp-1][i];
			V[i].nr[1] = (i+cnt)<L ? P[stp-1][i+cnt] : (-1);
		}
		sort( V , V+L , cmp );	nr = 0;
		for( i = 0 ; i < L ; i++ )
			P[stp][V[i].p] = i > 0 && V[i].nr[0] == V[i-1].nr[0] && V[i].nr[1] == V[i-1].nr[1] ? P[stp][V[i-1].p] : (nr++);
	}
	
	stp--;
	
	for( i = 0 ; i < L ; i++ )
		Z[i].p = i , Z[i].i = P[stp][i];
	
	sort(Z , Z+L , cmp1);
	
	sol = L - Z[0].p;
	
	for( i = 1 ; i < L ; i++ ){
		sol += L - Z[i].p - lcp( Z[i].p , Z[i-1].p );
	}
	
	g<<sol;
	
	return 0;
}