Cod sursa(job #912316)

Utilizator crushackPopescu Silviu crushack Data 12 martie 2013 11:59:32
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.73 kb
#include <stdio.h>
#include <algorithm>
#include <deque>
#define NMax 17010
#define LogN 17
using namespace std;

const char IN[]="substr.in",OUT[]="substr.out";

struct entry{
	int nr[2],p;
	bool operator<(entry const &b) const{
		return nr[0]<b.nr[0] || nr[0]==b.nr[0] && nr[1]<b.nr[1];
	}
} L[NMax];

int N,K,S,Rez;
int P[LogN][NMax],idx[NMax],v[NMax];
deque<int> d;
char s[NMax];

bool cmp(int x,int y){
	return P[S][x]<P[S][y];
}

void prefix(){

	int i,cnt,stp,p;

	for (i=1;i<=N;++i) P[0][i]=s[i];
	for (stp=cnt=1,p=0;(cnt>>1)<=N;cnt<<=1,++stp,++p)
	{
		for (i=1;i<=N;++i){
			L[i].nr[0]=P[stp-1][i];
			L[i].nr[1]=i+cnt<=N ? P[stp-1][i+cnt] : -1;
			L[i].p=i;
		}
		sort(L+1,L+N+1);
		for (i=1;i<=N;++i)
			P[stp][L[i].p]= i>1 && L[i].nr[0]==L[i-1].nr[0] && L[i].nr[1]==L[i-1].nr[1] ? P[stp][L[i-1].p] : i;
	}
	S=stp-1;
}

int lcp(int x,int y){

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

void add(int x){
	while (!d.empty() && (v[x]<v[d.back()] || x-d.back()>=K)) d.pop_back();
	d.push_back(x);
	while (!d.empty() && x-d.front()>=K) d.pop_front();
}

int main()
{
	int i;
	freopen(IN,"r",stdin);
	scanf("%d%d%s",&N,&K,s+1);--K;
	fclose(stdin);

	if (K==0){
		freopen(OUT,"w",stdout);
		printf("%d\n",N);
		fclose(stdout);
		return 0;
	}

	prefix();
	for (i=1;i<=N;++i) idx[i]=i;
	sort(idx+1,idx+N+1,cmp);

	/*for (i=1;i<=N;++i)
		printf("%s\n",s+idx[i]);*/

	for (i=2;i<=N;++i) v[i-1]=lcp(idx[i-1],idx[i]);
	for (i=1;i<N;++i){
		add(i);
		if (i>=K)
			Rez=max(Rez,v[d.front()]);
	}

	freopen(OUT,"w",stdout);
	printf("%d\n",Rez);
	fclose(stdout);

	return 0;
}