SP7586 NUMOFPAL - Number of Palindromes(回文树)
题意翻译
求一个串中包含几个回文串
题目描述
Each palindrome can be always created from the other palindromes, if a single character is also a palindrome. For example, the string "malayalam" can be created by some ways:
- malayalam = m + ala + y + ala + m
- malayalam = m + a + l + aya + l + a + m
We want to take the value of function NumPal(s) which is the number of different palindromes that can be created using the string S by the above method. If the same palindrome occurs more than once then all of them should be counted separately.
输入输出格式
输入格式:
The string S.
输出格式:
The value of function NumPal(s).
输入输出样例
输入样例#1: 复制
malayalam
输出样例#1: 复制
15
说明
Limitations
0 < |s| <= 1000
题解
这不是一道傻逼模板题吗?
我们只需要好好利用一下cnt数组,统计一下len不为1的回文串。
然后再加上一个|s|的长度就好了。
代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
struct node{
int fail,len,ch[26],cnt;
}t[1000010];
char s[1000100];
int n,ans;
void solve()
{
int k=0,tot=1;t[0].fail=t[1].fail=1;t[1].len=-1;s[0]='$';
for(int i=1;i<=n;i++)
{
while(s[i-t[k].len-1]!=s[i])k=t[k].fail;
if(!t[k].ch[s[i]-'a']){
t[++tot].len=t[k].len+2;
int j=t[k].fail;
while(s[i-t[j].len-1]!=s[i])j=t[j].fail;
t[tot].fail=t[j].ch[s[i]-'a'];
t[k].ch[s[i]-'a']=tot;
}
k=t[k].ch[s[i]-'a'];
t[k].cnt++;
}
for(int i=tot;i>=2;i--)
t[t[i].fail].cnt+=t[i].cnt;
for(int i=tot;i>=2;i--)
if(t[i].len!=1)
ans+=t[i].cnt;
}
int main()
{
scanf("%s",s+1);
n=strlen(s+1);
solve();
cout<<ans+n<<endl;
}