记录编号 381172 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [APIO 2014] Palindromes 最终得分 100
用户昵称 Gravatar__stdcall 是否通过 通过
代码语言 C++ 运行时间 3.776 s
提交时间 2017-03-11 08:32:05 内存使用 37.20 MiB
显示代码纯文本
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cctype>

using namespace std;
typedef long long ll;
const int MAXN = 300010, LOGN = 20;

int n;
char str[MAXN];
int sas[MAXN], san;
int mas[MAXN<<1], man;

namespace SA {
	int sa[MAXN], rk[MAXN], ht[MAXN];
	int tmp1[MAXN], tmp2[MAXN], cnt[MAXN];
	int minv[MAXN][LOGN], logn[MAXN];
	void solve( int m ) {
		int *x = tmp1, *y = tmp2;
		for( int i = 0; i < m; ++i ) cnt[i] = 0;
		for( int i = 0; i < san; ++i ) ++cnt[ x[i] = sas[i] ];
		for( int i = 1; i < m; ++i ) cnt[i] += cnt[i-1];
		for( int i = san-1; i >= 0; --i ) sa[--cnt[x[i]]] = i;
		for( int k = 1; k <= san; k <<= 1 ) {
			int p = 0;
			for( int i = san-k; i < san; ++i ) y[p++] = i;
			for( int i = 0; i < san; ++i ) if( sa[i] >= k ) y[p++] = sa[i]-k;
			for( int i = 0; i < m; ++i ) cnt[i] = 0;
			for( int i = 0; i < san; ++i ) ++cnt[x[i]];
			for( int i = 1; i < m; ++i ) cnt[i] += cnt[i-1];
			for( int i = san-1; i >= 0; --i ) sa[--cnt[x[y[i]]]] = y[i];
			swap(x,y), x[sa[0]] = 0, p = 1;
			for( int i = 1; i < san; ++i )
				x[sa[i]] = y[sa[i]] == y[sa[i-1]] && y[sa[i]+k] == y[sa[i-1]+k] ? p-1 : p++;
			if( p == san ) break;
			m = p;
		}
		for( int i = 0; i < san; ++i ) rk[i] = x[i];
		int k = 0;
		for( int i = 0; i < san; ++i ) {
			if( k ) --k;
			if( !rk[i] ) continue;
			int j = sa[rk[i]-1];
			while( sas[i+k] == sas[j+k] ) ++k;
			ht[rk[i]] = minv[rk[i]][0] = k;
		}
		for( int k = 1; (1<<k) <= san; ++k )
			for( int i = 0; i+(1<<k) <= san; ++i )
				minv[i][k] = min( minv[i][k-1], minv[i+(1<<(k-1))][k-1] );
		k = 0;
		for( int i = 1; i <= san; ++i ) {
			if( (1<<(k+1)) <= i ) ++k;
			logn[i] = k;
		}
	}
	int qmin( int l, int r ) {
		int k = logn[r-l+1];
		return min( minv[l][k], minv[r+1-(1<<k)][k] );
	}
}

void input() {
	scanf( "%s", str ), n = strlen(str);
    man = 0;
	for( int i = 0; i < n; ++i ) {
		sas[i] = str[i];
		mas[man++] = '#', mas[man++] = str[i];
	}
	sas[n] = 0, san = n+1;
	mas[man++] = '#';
	SA::solve(128);
}

ll ans = 1;
int rd[MAXN<<1];
void update( int p, int k ) {
	using namespace SA;
    p = rk[p];
	int LL = 0, LR = p;
	while( LL < LR ) {
		int mid = (LL+LR)>>1;
		if( qmin(mid+1,p) >= k ) LR = mid;
		else LL = mid+1;
	}
	int RL = p, RR = san-1;
	while( RL < RR ) {
		int mid = (RL+RR+1)>>1;
		if( qmin(p+1,mid) >= k ) RL = mid;
		else RR = mid-1;
	}
	ans = max( ans, ll(k)*(RL-LL+1) );
}
int cnt[26] = {0};
void manacher() {
	int mx = 0, p = 0;
	for( int i = 0; i < man; ++i ) {
		if( i < mx ) rd[i] = min( rd[2*p-i], mx-i );
		else rd[i] = 1;
		while( i+rd[i] < man && i-rd[i] >= 0 && mas[i+rd[i]] == mas[i-rd[i]] ) {
			if( islower( mas[i-rd[i]] ) ) update( (i-rd[i])/2, rd[i]+1 );
			++rd[i];
		}
		if( i+rd[i] > mx ) mx = i+rd[i], p = i;
	}
	for( int i = 0; i < n; ++i )
		ans = max( ans, (ll)++cnt[str[i]-'a'] );
	printf( "%lld\n", ans );
}

int main() {
	freopen( "apio2014_palindrome.in", "r", stdin );
	freopen( "apio2014_palindrome.out", "w", stdout );
	input(), manacher();
	return 0;
}