Submission #13454

#TimeUsernameProblemLanguageResultExecution timeMemory
13454aintaPalindromes (APIO14_palindrome)C++98
100 / 100
974 ms70816 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...