The Number of Palindromes
Problem Description
Now, you are given a string S. We want to know how many distinct substring of S which is palindrome.
Input
The first line of the input contains a single integer T(T<=20), which indicates number of test cases.
Each test case consists of a string S, whose length is less than 100000 and only contains lowercase letters.
Output
For every test case, you should output “Case #k:” first in a single line, where k indicates the case number and starts at 1. Then output the number of distinct substring of S which is palindrome.
Sample Input
3
aaaa
abab
abcd
Sample Output
Case #1: 4
Case #2: 4
Case #3: 4
解题思路:
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
char s[N];
struct PAM{
/**
len[u] : u 节点代表回文串的长度。
fa[u] : u 节点代表回文串的最长回文后缀代表的节点。
tran[u][c] : 转移函数,表示在 u 代表的回文串的两端加上字符 c 之后的回文串。
num[u] : 代表 u 节点代表回文串的回文后缀个数。
L[i] : 代表原字符串以 i 结尾的回文后缀长度。
size[u] : u 点代表的回文串的数量。
**/
int len[N],fa[N],size[N],num[N],tot,last,trans[N][27],L[N];
void init(){ // 初始化
len[0]=0;fa[0]=1;len[1]=-1;fa[1]=0;
tot=1;last=0;
memset(trans[1],0,sizeof(trans[1]));
memset(trans[0],0,sizeof(trans[0]));
}
int new_node(int x){ // 建立新节点
int now=++tot;
memset(trans[tot],0,sizeof(trans[tot]));
len[now]=x;
return now;
}
void ins(int c,int n){ // 增量法构造
int u=last;
while(s[n-len[u]-1]!=s[n])u=fa[u];
if(trans[u][c]==0){
int now=new_node(len[u]+2);
int v=fa[u];
while(s[n-len[v]-1]!=s[n])v=fa[v];
fa[now]=trans[v][c];
trans[u][c]=now;
num[now]=num[fa[now]]+1;
}
last=trans[u][c];size[last]++;
L[n]=len[last];
}
void build(char *s){
int len = strlen(s);
for(int i = 0 ; i < len ; i ++){
ins(s[i]-'a',i);
}
}
}pam;
int main(){
int n,m;
int cas = 1;
cin>>n;
while(n--){
cin>>s;
pam.init();
pam.build(s);
cout<<"Case #"<<cas++<<": "<<pam.tot-1<<endl;
}
return 0;
}