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;
}
posted @ 2018-06-30 08:38  Epiphyllum_thief  阅读(170)  评论(0编辑  收藏  举报