Cod sursa(job #522756)

Utilizator indestructiblecont de teste indestructible Data 16 ianuarie 2011 00:46:40
Problema Substr Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <stdio.h>
#include <vector>
#define NMAX 16505
#define MOD1 100007
#define MOD2 100021
#define P 127
#define ll long long
#define pii pair <int,int>
#define pb push_back
#define mp make_pair
#define f first
#define s second
using namespace std;
int n,k,B[NMAX],C[NMAX],P1[NMAX],P2[NMAX],found;
char A[NMAX];
vector <pii> D[MOD1];
void precompute()
{
	int i;
	P1[0]=1; P2[0]=1;
	for (i=1; i<=n; i++)
	{
		B[i]=(B[i-1]*P+A[i])%MOD1;
		C[i]=(C[i-1]*P+A[i])%MOD2;
		P1[i]=(P1[i-1]*P)%MOD1;
		P2[i]=(P2[i-1]*P)%MOD2;
	}
}
inline int code1(int st,int dr)
{
	int act1,act2;
	act1=((ll)B[st-1]*P1[dr-st+1])%MOD1;
	act2=B[dr]-act1;
	if (act2<0) 
		act2+=MOD1;
	return act2;
}
inline int code2(int st,int dr)
{
	int act1,act2;
	act1=((ll)C[st-1]*P2[dr-st+1])%MOD2;
	act2=C[dr]-act1;
	if (act2<0) 
		act2+=MOD2;
	return act2;
}
void add(int x,int y)
{
	int i,z;
	for (i=0; i<D[x].size(); i++)
	{
		z=D[x][i].f;
		if (z==y)
		{
			D[x][i].s++;
			if (D[x][i].s>=k)
				found=1;
			return ;
		}
	}
	D[x].pb(mp(y,1));
	if (D[x][D[x].size()-1].s>k)
		found=1;
}
int ok(int val)
{
	int i,x,y;
	found=0;
	for (i=1; i<=n-val+1; i++)
	{
		x=code1(i,i+val-1); y=code2(i,i+val-1);
		add(x,y);
	}
	for (i=1; i<=n-val+1; i++)
	{
		x=code1(i,i+val-1);
		D[x].clear();
	}
	return found;
}
int cbin()
{
	int i,step=1;
	for (step=1; step<=n; step<<=1);
	for (i=0; step; step>>=1)
		if (i+step<=n && ok(i+step))
			i+=step;
	return i;
}
int main()
{
	freopen("substr.in","r",stdin);
	freopen("substr.out","w",stdout);
	scanf("%d%d\n",&n,&k);
	fgets(A+1,NMAX,stdin);
	precompute();
	printf("%d\n",cbin());
	return 0;
}