Cod sursa(job #3135488)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 3 iunie 2023 14:20:21
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.48 kb
//Ilie Dumitru
#include<cstdio>
#include<deque>
const int NMAX=16500;
const int MOD=9901;

struct suffixArray
{
	int N;
	int perm[NMAX];
	int eqvCls[NMAX], nrEqvCls;
	int cnt[NMAX], pos[NMAX];
	int lcp[NMAX];
	char* s;

	void init(char* _s, int _N)
	{
		s=_s;
		N=_N;
		computeArray();
	}

	void radixSort(int sz)
	{
		int i;

		for(i=0;i<nrEqvCls;++i)
			cnt[i]=0;
		for(i=0;i<N;++i)
			++cnt[eqvCls[perm[i]]];

		pos[0]=0;
		for(i=1;i<nrEqvCls;++i)
			pos[i]=pos[i-1]+cnt[i-1];

		//cnt is auxiliary
		for(i=0;i<N;++i)
			cnt[pos[eqvCls[(perm[i]-sz+N)%N]]++]=(perm[i]-sz+N)%N;
		for(i=0;i<N;++i)
			perm[i]=cnt[i];
	}

	void computeArray()
	{
		int i, k;

		{
			//k=0
			for(i=0;i<256;++i)
				cnt[i]=0;
			for(i=0;i<N;++i)
				++cnt[(int)s[i]];

			pos[0]=0;
			for(i=1;i<256;++i)
				pos[i]=pos[i-1]+cnt[i-1];

			for(i=0;i<N;++i)
				perm[pos[(int)s[i]]++]=i;

			eqvCls[perm[0]]=0;
			for(i=1;i<N;++i)
				if(s[perm[i]]==s[perm[i-1]])
					eqvCls[perm[i]]=eqvCls[perm[i-1]];
				else
					eqvCls[perm[i]]=eqvCls[perm[i-1]]+1;
			nrEqvCls=eqvCls[perm[N-1]]+1;
		}

		for(k=0;(1<<k)<N && nrEqvCls<N;++k)
		{
			//k->k+1
			radixSort(1<<k);

			//cnt is auxiliary
			cnt[perm[0]]=0;
			for(i=1;i<N;++i)
				if(eqvCls[perm[i]]==eqvCls[perm[i-1]] && eqvCls[(perm[i]+(1<<k))%N]==eqvCls[(perm[i-1]+(1<<k))%N])
					cnt[perm[i]]=cnt[perm[i-1]];
				else
					cnt[perm[i]]=cnt[perm[i-1]]+1;
			for(i=0;i<N;++i)
				eqvCls[i]=cnt[i];
			nrEqvCls=eqvCls[perm[N-1]]+1;
		}
	}

	void buildLcp()
	{
		int i, j, k=0;

		for(i=0;i+1<N;++i)
		{
			j=perm[eqvCls[i]-1];
			while(s[i+k]==s[j+k])
				++k;
			lcp[eqvCls[i]-1]=k;
			if(k)
				--k;
		}
	}
};

int N, K;
char s[NMAX];
suffixArray S;
std::deque<int> dq;

int main()
{
	FILE* f=fopen("substr.in", "r"), *g=fopen("substr.out", "w");
	int i, max;

	fscanf(f, "%d%d", &N, &K);
	if(K==1)
		fprintf(g, "%d\n", N);
	else
	{
		fgets(s, NMAX, f);
		fgets(s, NMAX, f);
		s[N]='$';
		S.init(s, ++N);
		S.buildLcp();

		for(i=0;i+1<K;++i)
		{
			while(!dq.empty() && S.lcp[dq.back()]>=S.lcp[i])
				dq.pop_back();
			dq.push_back(i);
		}
		max=S.lcp[dq.front()];

		for(;i<N;++i)
		{
			if(dq.front()==i-K+1)
				dq.pop_front();
			while(!dq.empty() && S.lcp[dq.back()]>=S.lcp[i])
				dq.pop_back();
			dq.push_back(i);
			if(S.lcp[dq.front()]>max)
				max=S.lcp[dq.front()];
		}

		fprintf(g, "%d\n", max);
	}

	fclose(f);
	fclose(g);
	return 0;
}