Pagini recente » Cod sursa (job #885260) | Cod sursa (job #3178292) | Cod sursa (job #501791) | Cod sursa (job #775208) | Cod sursa (job #3143705)
#include <fstream>
#include <algorithm>
#include <string>
using namespace std;
ifstream fin("substr.in");
ofstream fout("substr.out");
#define DIM 16500
#define LOG 17
typedef pair<pair<int, int>, int> PIII;
int n, k;
int P[LOG + 1][DIM + 1], lg[DIM + 5], a[DIM + 5];
PIII v[DIM + 5];
string s;
//cel mai lung prefix comun;
static inline int lcp(int i, int j) {
if(i == j)
return n - i;
int ans = 0;
for(int k = lg[n]; k >= 0; k--)
if(P[k][i] == P[k][j]) {
ans += (1 << k);
i += (1 << k);
j += (1 << k);
}
return ans;
}
//S(k, j) = Secventa de caractere din intervalul [j, j + 2^k - 1];
//P[k][j] = Pozitia Sufixului S(k, j), in sirul sortat si incepe pe pozitia j;
static inline void Build_suffix_array(string s) {
s = '$' + s; //santinela;
for(int i = 1; i <= n; i++)
P[0][i] = s[i] - '0';
for(int k = 1; k <= lg[n] + 2; k++) {
for(int j = 1; j <= n; j++) {
int x = (1 << (k - 1)); //lungimea intervalului;
if(j + x <= n)
v[j] = {{P[k - 1][j], P[k - 1][j + x]}, j};
else v[j] = {{P[k - 1][j], -1}, j};
}
sort(v + 1, v + n + 1); //sortez sa;
int nr = 0;
for(int j = 1; j <= n; j++) {
if(v[j].first != v[j - 1].first) //daca sunt mai multe egale au aceeasi pozitie;
nr++;
P[k][v[j].second] = nr;
}
}
}
int main() {
fin >> n >> k;
fin >> s;
if(k == 1) {
fout << n;
return 0;
}
lg[1] = 0;
for(int i = 2; i <= n; i++)
lg[i] += lg[i / 2] + 1;
Build_suffix_array(s);
for(int i = 1; i <= n; i++)
a[P[lg[n] + 2][i]] = i;
int ans = 0;
for(int i = 1; i <= n - k + 1; i++) {
int aux = lcp(a[i], a[i + k - 1]);
ans = max(ans, aux);
}
fout << ans;
return 0;
}