https://atcoder.jp/contests/abc141/tasks/abc141_e
//#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN = 20005;
char s[MAXN];
int n, k;
int t1[MAXN], t2[MAXN], c[MAXN];
int _rank[MAXN], height[MAXN], sa[MAXN];
bool cmp(int *r, int a, int b, int l) { return r[a] == r[b] && r[a + l] == r[b + l]; }
void da(char str[], int sa[], int rank[], int height[], int n, int m) {
n++;
int i, j, p, *x = t1, *y = t2;
for (i = 0; i < m; i++)c[i] = 0;
for (i = 0; i < n; i++)c[x[i] = str[i]]++;
for (i = 1; i < m; i++)c[i] += c[i - 1];
for (i = n - 1; i >= 0; i--)sa[--c[x[i]]] = i;
for (j = 1; j <= n; j <<= 1) {
p = 0;
for (i = n - j; i < n; i++)
y[p++] = i;
for (i = 0; i < n; i++)
if (sa[i] >= j)
y[p++] = sa[i] - j;
for (i = 0; i < m; i++)c[i] = 0;
for (i = 0; i < n; i++)c[x[y[i]]]++;
for (i = 1; i < m; i++)c[i] += c[i - 1];
for (i = n - 1; i >= 0; i--)
sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = 1;
x[sa[0]] = 0;
for (i = 1; i < n; i++) x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++;
if (p >= n)break;
m = p;
}
int k = 0;
n--;
for (i = 0; i <= n; i++)rank[sa[i]] = i;
for (i = 0; i < n; i++) {
if (k)k--;
j = sa[rank[i] - 1];
while (str[i + k] == str[j + k])k++;
height[rank[i]] = k;
}
}
int getRepeatTimes(int l, int len) {
int res = l;
while (height[res] >= len && res <= n) res++;
return res - l + 1;
}
/**
* ÅжÏÊÇ·ñÓ㈶ÈΪlenµÄÖØžŽkŽÎŒ°ÒÔÉϵĵÄ×ÓŽ®
* @param len
* @return
*/
bool repeatsMoreThanK(int len) {
int l = 2;
while (l <= n) {
if (height[l] >= len) {
int times = getRepeatTimes(l, len);
if (times >= k)
return true;
l += times - 1;
} else ++l;
}
return false;
}
bool repeatsMoreThanK(int n, int k) {
int maxi = -1, mini = 0x3f3f3f3f;
for (int i = 1; i <= n; ++i) {
if (height[i] < k)
maxi = sa[i], mini = sa[i];
else {
maxi = max(maxi, max(sa[i], sa[i - 1]));
mini = min(mini, min(sa[i], sa[i - 1]));
if (maxi - mini >= k) return true;
}
}
return false;
}
int main() {
k = 2;
scanf("%d", &n);
scanf("%s", s);
s[n] = 0;
da(s, sa, _rank, height, n, 128);
int ans = 0, l = 1, r = n;
while (l <= r) {
int mid = (l + r) >> 1;
if (repeatsMoreThanK(n, mid))
ans = mid, l = mid + 1;
else
r = mid - 1;
}
printf("%d\n", ans);
return 0;
}
//#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN = 20005;
char s[MAXN];
int n, k;
typedef long long ll;
const ll mod = static_cast<const ll>(1e9 + 7);
const int maxn = static_cast<const int>(1e6 + 5);
#define base 131
ll po[maxn];
ll po1[maxn];
// 0 based, l, arr inclusive.
ll getHash(const ll _hash[], int l, int r) {
return (_hash[r] - _hash[l - 1] * po[r - l + 1] % mod + mod) % mod;
}
ll getHash2(const ll _hash[], int l, int r) {
return (_hash[r] - _hash[l - 1] * po1[r - l + 1] % mod + mod) % mod;
}
ll strHash[maxn];
ll strHash2[maxn];
void init() {
po[0] = 1;
for (int i = 1; i < maxn; ++i)
po[i] = (po[i - 1] * base) % mod;
po1[0] = 1;
for (int i = 1; i < maxn; ++i)
po1[i] = (po1[i - 1] * 97) % mod;
}
void initHash(const char *str, ll *_hash, int ba) {
_hash[0] = str[0] - '0';
for (int i = 1; str[i]; i++)
_hash[i] = ((_hash[i - 1] * ba) % mod + str[i] - '0') % mod;
}
bool repeatsMoreThanK(int len) {
int cnt = 1;
for (int i = 0; i + len - 1 < n; ++i) {
ll baseHash = getHash(strHash, i, i + len - 1);
ll baseHash2 = getHash2(strHash2, i, i + len - 1);
cnt = 1;
for (int j = i + len; j + len - 1 < n; ++j) {
ll currHash = getHash(strHash, j, j + len - 1);
ll currHash2 = getHash2(strHash2, j, j + len - 1);
if (currHash == baseHash && baseHash2 == currHash2) {
++cnt;
if (cnt >= k)
return true;
}
}
}
return false;
}
int main() {
k = 2;
scanf("%d", &n);
scanf("%s", s);
init();
initHash(s, strHash, 131);
initHash(s, strHash2, 97);
// da(s, sa, _rank, height, n, 128);
int ans = 0, l = 1, r = n;
while (l <= r) {
int mid = (l + r) >> 1;
if (repeatsMoreThanK(mid))
ans = mid, l = mid + 1;
else
r = mid - 1;
}
printf("%d\n", ans);
return 0;
}
#include
using namespace std;
int n;
char S[5005];
int A[5005];
int solve(char S[], int n) {
int l = -1, r = -1;
for (int i = 1; i < n; ++i) {
if (i <= r) A[i] = min(r - i, A[i - l]);
else A[i] = -1;
while (i + A[i] + 1 < n && S[i + A[i] + 1] == S[A[i] + 1]) ++A[i];
if (r < i + A[i]) r = i + A[i], l = i;
}
int ret = 0;
for (int i = 1; i < n; ++i) {
ret = max(ret, min(A[i] + 1, i));
}
return ret;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> S + 1;
int ans = 0;
for (int i = 1; i <= n; ++i) ans = max(ans, solve(S + i, n - i + 1));
cout << ans;
return 0;
}