UVA 11475 Extend to Palindrome hash

题意:

给出一个字符串,让你往后添加最少的字符,使其成为回文串。

分析:

题目就相当于求后缀字符串为回文串的最长长度,判断回文串要O(n)时间,直接判断肯定不行。我们从后往前枚举,每次字符串与上一个字符串仅相差一个字符,所以我们将字符hash,每次的hash值就与上一个hash有关。于是我们判断后缀字符串的从左往右的hash值是否与从右往左的hash值相等即可。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=100000+5;
const ll mod=1000000007;
char str[maxn];

int main()
{
//    freopen("in.txt","r",stdin);
    while(~scanf("%s",str))
    {
        int len=strlen(str);
        int base1=131,base2=1313;
        ll pre1,pre2,suf1,suf2;
        ll tmp1=1,tmp2=1;
        pre1=pre2=suf1=suf2=0;
        int ans;
        for(int i=len-1;i>=0;i--)
        {
            pre1=(base1*pre1+str[i])%mod;   //进行两次hash
            pre2=(base2*pre2+str[i])%mod;
            suf1=(str[i]*tmp1+suf1)%mod;
            suf2=(str[i]*tmp2+suf2)%mod;
            tmp1=base1*tmp1%mod;
            tmp2=base2*tmp2%mod;
            if(pre1==suf1 && pre2==suf2) ans=i;
        }
        printf("%s",str);
        for(int i=ans-1;i>=0;i--)
            putchar(str[i]);
        puts("");
    }
    return 0;
}

 

posted @ 2017-07-19 10:17  Pacify  阅读(175)  评论(0编辑  收藏  举报