之前有一种普遍使用的字符串hash:
可以有效地处理字符串的子串:
再者:还有可以代替KMP的hash:
+
//
现在我们从一道题目入手(SPOJ-EPALIN):
题意:
对给定字符串S,求以S为前缀的、长度最小的回文串并输出它
网上由两种解法:
一、KMP+逆字符串
二、hash+回文
我还有一种解法:马拉车+标记以S[LEN-1]为结尾的最长回文串长度的左端点
HASH回文:
1.回文的特点:
假设我们有一个回文串:
根据回文串特点:
我们有:(条件一)
..
..
首先,从一般的hash式子,我们有:(式子一)
之后,简化式子,我们有:(式子二)
又因为:有条件一:
所以:式子二)
我们令式子二的值为hash2
所以有了等价关系:
ORZ.....
CODE:
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef unsigned long long ull;
const int MAXN = 100000+100;
const int prime = 107;
const int mod = 1e9+7;
int n;
char s[MAXN];
int main()
{
while(~scanf("%s",s))
{
n=strlen(s);
ull pow=1;
ull start=0;
ull a1=0,a2=0;
for(int i=n-1;i>=0;--i)
{
a1=(a1*prime+s[i])%mod;
a2=(a2+pow*s[i])%mod;
//printf("%d %d\n",a1,a2);
if(a1==a2)
start=i;
pow=(pow*prime)%mod;
}
for(int i=0;i<n;++i)
putchar(s[i]);
for(int i=start-1;i>=0;--i)
putchar(s[i]);
printf("\n");
}
}