codeforces7D Palindrome Degree(manacher&dp或Hsh&dp)

D. Palindrome Degree
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

String s of length n is called k-palindrome, if it is a palindrome itself, and its prefix and suffix of length  are(k - 1)-palindromes. By definition, any string (even empty) is 0-palindrome.

Let's call the palindrome degree of string s such a maximum number k, for which s is k-palindrome. For example, "abaaba" has degree equals to 3.

You are given a string. Your task is to find the sum of the palindrome degrees of all its prefixes.

Input

The first line of the input data contains a non-empty string, consisting of Latin letters and digits. The length of the string does not exceed 5·106. The string is case-sensitive.

Output

Output the only number — the sum of the polindrome degrees of all the string's prefixes.

Sample test(s)
input
a2A
output
1
input
abacaba
output
6

题意:

定义回文串的度为length 即前半部分串的度或后半部分的度+1。先再给你一个字符串。

要你求出他全部前缀度的和。

思路:

先用manacher求出以每一个位置为中心最大回文串的长度。

dp[i]记录长度为i的前缀的度。那么dp[i+1]分奇偶用到前面的度即可了。

具体见代码:

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=5110000;
int p[maxn<<1],dp[maxn],len;
char buf[maxn],st[maxn<<1];
void init()
{
    int i;
    len=strlen(buf);
    st[0]='$',st[1]='#';
    for(i=0;i<len;i++)
        st[2*i+2]=buf[i],st[2*i+3]='#';
    len=2*len+2;
}
void manacher()
{
    int i,id,mx=0;
    for(i=1;i<len;i++)
    {
        p[i]=mx>i?

min(mx-i,p[2*id-i]):1; while(st[i+p[i]]==st[i-p[i]]) p[i]++; if(i+p[i]>mx) mx=i+p[i],id=i; } } int main() { int i,ans,n; while(~scanf("%s",buf)) { ans=0,n=strlen(buf); init(); manacher(); ans=dp[0]=1; for(i=1;i<n;i++) { if(p[i+2]-1>=i+1)//推断该前缀是否回文。字符串从0開始。

i+2为0到i在p数组对称中心无论回文串长度使是奇数还是偶数的。p[i]-1为最大回文长度 { if(i&1) dp[i]=dp[i/2]+1; else dp[i]=dp[i/2-1]+1; } ans+=dp[i]; } printf("%d\n",ans); } return 0; }


Hash的做法就比較简单了。

具体见代码:

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=5110000;;
unsigned long long H1[maxn],H2[maxn],xp[maxn],ha,hb,x=123;
int dp[maxn],len;
char buf[maxn],rbuf[maxn];
void init()
{
    int i;
    len=strlen(buf);
    H1[len]=H2[len]=0;
    xp[0]=1;
    for(i=len-1;i>=0;i--)
    {
        H1[i]=H1[i+1]*x+buf[i];
        H2[i]=H2[i+1]*x+rbuf[i];
        xp[len-i]=xp[len-i-1]*x;
    }
}
unsigned long long getHash(unsigned long long *HS,int s,int L)
{
    return HS[s]-HS[s+L]*xp[L];
}
int main()
{
    int i,ans;
    while(~scanf("%s",buf))
    {
        ans=0,len=strlen(buf);
        for(i=0;i<len;i++)
            rbuf[i]=buf[len-i-1];
        init();
        ans=dp[0]=1;
        for(i=1;i<len;i++)
        {
            ha=getHash(H1,0,i+1);
            hb=getHash(H2,len-i-1,i+1);
            if(ha==hb)
            {
                if(i&1)
                    dp[i]=dp[i/2]+1;
                else
                    dp[i]=dp[i/2-1]+1;
            }
            else
                dp[i]=0;
            ans+=dp[i];
        }
        printf("%d\n",ans);
    }
    return 0;
}


posted @ 2017-05-24 14:43  mfmdaoyou  阅读(262)  评论(0编辑  收藏  举报