# Palindrome

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 602    Accepted Submission(s): 234

Problem Description
Alice like strings, especially long strings. For each string, she has a special evaluation system to judge how elegant the string is. She defines that a string S[1..3n2](n2) is one-and-half palindromic if and only if it satisfies S[i]=S[2ni]=S[2n+i2](1in).For example, abcbabc is one-and-half palindromic string, and abccbaabc is not. Now, Alice has generated some long strings. She ask for your help to find how many substrings which is one-and-half palindromic.

Input
The first line is the number of test cases. For each test case, there is only one line containing a string(the length of strings is less than or equal to 500000), this string only consists of lowercase letters.

Output
For each test case, output a integer donating the number of one-and-half palindromic substrings.

Sample Input
1ababcbabccbaabc

Sample Output
2
Hint
In the example input, there are two substrings which are one-and-half palindromic strings, $abab$ and $abcbabc$.

Source

2017中国大学生程序设计竞赛-哈尔滨站-重现赛（感谢哈理工）

A和B构成回文串同时，B和C构成回文串。

j>i

i+r[i]>j

j-r[j]<i

#include<bits/stdc++.h>
#define N 500010
#define LL long long
using namespace std;
char s[N],ss[N<<1];
int r[N<<1],len,n,d[N];
vector<int>g[N];

void Manacher()
{
int ll = strlen(s),p,mx=0;
len=2; ss[0] = '\$'; ss[1] = '#';
for (int i = 0; i < ll; i++)ss[len++] = s[i],ss[len++] = '#';
ss[len] = '\0';
for (int i = 1; i < len; i++)
{
if (i<mx) r[i]=min(r[2*p-i],mx-i);else r[i] = 1;
while (ss[i-r[i]]==ss[i+r[i]]) r[i]++;
if (mx<i+r[i])p=i,mx=i+r[i];
}
}

void updata(int x,int y)
{
for (int i=x;i<=n;i+=i&-i) d[i]+=y;
}

LL sum(int x)
{
LL t=0; for (int i=x;i;i-=i&-i) t+=d[i]; return t;
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);LL ans=0;
n=strlen(s);memset(r,0,sizeof r);
Manacher();
for (int i=0;i<=n;i++) d[i]=0,g[i].clear();
for (int i=1;i<=n;i++) r[i]=r[i<<1]>>1,g[i-r[i]].push_back(i);
for (int i=1;i<=n;i++)
{
for (int j=0;j<g[i-1].size();j++) updata(g[i-1][j],1);
if (r[i]>1)ans+=sum(i+r[i]-1)-sum(i);
}
printf("%I64d\n",ans);
}
}


• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120