53 lines
1.3 KiB
C++
53 lines
1.3 KiB
C++
#include <algorithm>
|
|
#include <cassert>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
using namespace std;
|
|
typedef long long LL;
|
|
const int maxn = 1e6 + 10;
|
|
const __int128_t kBase = 114513;
|
|
const __int128_t kMod = 180143985094819841ll;
|
|
int n;
|
|
char s[maxn];
|
|
int f[maxn];
|
|
__int128_t kPow[maxn], hsh[maxn];
|
|
inline bool IsSame(int L1, int R1, int L2, int R2) {
|
|
if (R1 - L1 != R2 - L2) return false;
|
|
__int128_t hsh_s1 =
|
|
((hsh[R1] - hsh[L1 - 1] * kPow[R1 - L1 + 1]) % kMod + kMod) % kMod;
|
|
__int128_t hsh_s2 =
|
|
((hsh[R2] - hsh[L2 - 1] * kPow[R2 - L2 + 1]) % kMod + kMod) % kMod;
|
|
return hsh_s1 == hsh_s2;
|
|
}
|
|
int main() {
|
|
#ifdef local
|
|
freopen("pro.in", "r", stdin);
|
|
#endif
|
|
scanf("%d%s", &n, s + 1);
|
|
kPow[0] = 1;
|
|
for (int i = 1; i <= n; i++) {
|
|
kPow[i] = (kPow[i - 1] * kBase) % kMod;
|
|
}
|
|
for (int i = 1; i <= n; i++) {
|
|
hsh[i] = (hsh[i - 1] * kBase + s[i] - 'a' + 1) % kMod;
|
|
}
|
|
for (int i = n / 2; i > 0; i--) {
|
|
f[i] = f[i + 1] + 2;
|
|
while (f[i]) {
|
|
if ((i + f[i]) * 2 > n)
|
|
f[i]--;
|
|
else if (!IsSame(i + 1, i + f[i], n - i - f[i] + 1, n - i))
|
|
f[i]--;
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
int ans = 0;
|
|
for (int i = 1; i * 2 <= n; i++)
|
|
if (IsSame(1, i, n - i + 1, n)) {
|
|
fprintf(stderr, "find i=%d\n", i);
|
|
ans = max(ans, i + f[i]);
|
|
}
|
|
printf("%d\n", ans);
|
|
return 0;
|
|
} |