이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<stdio.h>
#include<algorithm>
#define N_ 300010
#define N2_ 600010
#define SZ 524288
using namespace std;
char p[N2_];
int LCP[N2_][20], SA[N2_], Num[N2_], po[N2_];
struct Arr{
int a, b;
}Li[N2_];
int n, m, C[N2_], ord[N2_], ord2[N2_];
void Suffix_Array(){
int i, L = 1, M, cnt;
for (i = 1; i <= m; i++){
Li[i].a = p[i], Li[i].b = 0;
}
while (1){
M = max(m, 256);
for (i = 1; i <= m; i++)C[Li[i].b]++;
for (i = 1; i <= M; i++)C[i] += C[i - 1];
for (i = 1; i <= m; i++)ord[C[Li[i].b]--] = i;
for (i = 0; i <= M; i++)C[i] = 0;
for (i = 1; i <= m; i++)C[Li[i].a]++;
for (i = 1; i <= M; i++)C[i] += C[i - 1];
for (i = m; i >= 1; i--)ord2[C[Li[ord[i]].a]--] = ord[i];
for (i = 0; i <= M; i++)C[i] = 0;
cnt = 0;
for (i = 1; i <= m; i++){
if (i == 1 || Li[ord2[i]].a != Li[ord2[i - 1]].a || Li[ord2[i]].b != Li[ord2[i - 1]].b)cnt++;
SA[ord2[i]] = cnt;
}
if (L >= m)break;
for (i = 1; i <= m; i++){
Li[i].a = SA[i];
if (i + L > m)Li[i].b = 0;
else Li[i].b = SA[i + L];
}
L *= 2;
}
for (i = 1; i <= m; i++)Num[SA[i]] = i;
}
void Make_LCP(){
int i, L = 0, x, j;
for (i = 1; i <= m; i++){
if (SA[i] == m)continue;
if (L)L--;
x = Num[SA[i] + 1];
while (p[i + L] == p[x + L])L++;
LCP[SA[i]][0] = L;
}
for (i = 0; i < 19; i++){
for (j = 1; j <= m; j++){
if (j + (1 << i) <= m) LCP[j][i + 1] = min(LCP[j][i], LCP[j + (1 << i)][i]);
}
}
}
int get_LCP(int b, int e){
if (b>e)return get_LCP(e, b);
int d = po[e - b];
return min(LCP[b][d], LCP[e - (1 << d)][d]);
}
int w[N2_], S[N_];
long long Res;
void Do(int ck){
int i, L = 0, j, Sum;
for (i = 1; i <= m + 1; i++){
Sum = 0;
while (L > LCP[i - 1][0]){
Sum += S[L];
S[L] = 0;
Res = max(Res, (long long)Sum * (L * 2 - ck));
L--;
}
if (i == m + 1)break;
S[L] += Sum;
L = max(L, w[i]);
S[w[i]]++;
}
}
int main(){
int i;
scanf("%s", p + 1);
for (i = 1; p[i]; i++);
n = i - 1;
m = n + n + 1;
p[n + 1] = ' ';
for (i = 1; i <= n; i++)p[m + 1 - i] = p[i];
Suffix_Array();
Make_LCP();
for (i = 1; i <= m; i++){
po[i] = po[i - 1];
if ((1 << (po[i] + 1)) == i)po[i]++;
}
for (i = 1; i <= n; i++)w[SA[i]] = get_LCP(SA[i], SA[m + 1 - i]);
Do(1);
w[SA[1]] = 0;
for (i = 2; i <= n; i++)w[SA[i]] = get_LCP(SA[i], SA[m + 2 - i]);
Do(0);
printf("%lld\n", Res);
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |