codeforces 159D
给出一个字符出,求取这个字符串中互相不覆盖的两个回文子串的对数。
#include
#include
#include
#include
#define MAX 2007
using namespace std;
typedef long long LL;
int temp[MAX<<1];
int Len[MAX<<1];
int init ( char *st , int n )
{
int i;
temp[0] = -1;
for ( int i = 1 ; i <= 2*n ; i+=2 )
{
temp[i] = -2;
temp[i+1] = st[i/2];
}
temp[2*n+1] = -2;
temp[2*n+2] = -3;
temp[2*n+3] = 0;
return 2*n+1;
}
void manacher ( int *st , int len )
{
int mx = 0 , ans = 0 , po = 0;
for ( int i = 1 ; i <= len ; i++ )
{
if ( mx > i )
Len[i] = min ( mx - i , Len[2*po-i] );
else
Len[i] = 1;
while ( st[i-Len[i]] == st[i+Len[i]] )
Len[i]++;
if ( Len[i]+i > mx )
mx = Len[i]+i , po = i;
}
}
char s[MAX];
LL a[MAX<<1],ans;
int main ( )
{
while ( ~scanf ( "%s" , s ) )
{
ans = 0;
memset ( a , 0 , sizeof ( a ) );
int n = strlen ( s );
manacher ( temp , init ( s, n ) );
for ( int i = 1 ; i <= 2*n ; i++ )
{
int x = Len[i];
if ( i&1 )
for ( int j = 1 ; j < x ; j += 2 )
a[i+j]++;
else
for ( int j = 0 ; j < x ; j += 2 )
a[i+j]++;
}
a[0] = 0;
for ( int i = 1 ; i <= 2*n ; i++ )
a[i] += a[i-1];
for ( int i = 1 ; i <= 2*n ; i++ )
{
int x = Len[i];
if ( i&1 )
for ( int j = 1 ; j < x ; j += 2 )
ans += a[i-j-1];
else
for ( int j = 0 ; j < x ; j += 2 )
ans += a[i-j-1];
}
printf ( "%lld\n" , ans );
}
}