Pagini recente » Cod sursa (job #936018) | Cod sursa (job #1917653) | Cod sursa (job #1415261) | Cod sursa (job #1683354) | Cod sursa (job #2450268)
#include <fstream>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
typedef pair < int, int > PII;
ifstream f("substr.in");
ofstream g("substr.out");
const int NMAX = 17e3 + 5, LOGMAX = 15;
int N, K, Log2[NMAX], ans = 0;
int Ord[LOGMAX + 5][NMAX];
PII Code[NMAX];
pair < PII, int > V[NMAX];
char S[NMAX];
int Start[NMAX];
/// Normalization:
map < char, bool > mp;
int ind, cnt[300];
///
static inline void Suffix_Array ()
{
for(int i = 1; i <= N; ++i)
Ord[0][i] = cnt[(int)S[i]];
for(int i = 1; i <= Log2[N] + 2; ++i)
{
for(int j = 1; j <= N; ++j)
Code[j] = {Ord[i - 1][j], (j + (1 << (i - 1)) <= N) ? Ord[i - 1][j + (1 << (i - 1))] : 0};
for(int j = 1; j <= N; ++j)
V[j] = {Code[j], j};
sort(V + 1, V + N + 1);
int k = 0;
for(int j = 1; j <= N; ++j)
{
if(V[j].first != V[j - 1].first)
++k;
Ord[i][V[j].second] = k;
}
}
return;
}
static inline int LCP (int Left, int Right)
{
int r = 0;
if(Left > Right)
swap(Left, Right);
int Dim = min(N - Left + 1, N - Right + 1);
int p2 = Log2[Dim];
for(int i = p2; i >= 0 && Left <= N && Right <= N; --i)
{
if(Ord[i][Left] == Ord[i][Right])
{
r += (1 << i);
Left += (1 << i);
Right += (1 << i);
}
}
return r;
}
int main()
{
f.tie(NULL);
f >> N >> K;
if(K == 1)
{
g << N << '\n';
return 0;
}
if(K == N)
{
bool Ok = true;
for(int i = 2; i <= N && Ok; ++i)
if(S[i] != S[i - 1])
Ok = false;
if(Ok)
g << 1;
else
g << 0;
g << '\n';
return 0;
}
///
Log2[1] = 0;
for(int i = 2; i <= N; ++i)
Log2[i] = 1 + Log2[i / 2];
///
///
f >> (S + 1);
for(int i = 1; i <= N; ++i)
mp[S[i]] = true;
for(auto it : mp)
{
++ind;
cnt[(int)it.first] = ind;
}
///
Suffix_Array();
for(int i = 1; i <= N; ++i)
Start[Ord[Log2[N] + 2][i]] = i;
for(int i = 1; i <= N - K + 1; ++i)
ans = max(ans, LCP(Start[i], Start[i + K - 1]));
g << ans << '\n';
return 0;
}