标签:
题意:求一个字符串(len<=110000)的最长回文串
解题思路:一般解法是manacher,但是这一题用hash也是可以ac的
假设当前判断的是以i为中心偶数最长回文串,那么s[2*i+1-k……i]与s[i+1……k]的哈希值必定相同
假设当前判断的是以i为中心奇数最长回文串,那么s[2*i-k……i-1]与s[i+1……k]的哈希值必定相同
用二分求出相应的k
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 using namespace std; 7 #define ull unsigned long long 8 const int inf = 110000+10; 9 const ull bas = 311; 10 ull lhas[inf], rhas[inf], base[inf]; 11 char s[inf]; 12 int len, ans, even, odd; 13 int getans(int li, int x, int y) 14 { 15 int l = y, r = li; 16 while(l<=r) 17 { 18 int mid = (l+r)/2; 19 int j = x+y-mid; 20 int right = rhas[mid] - rhas[y-1]*base[mid-y+1]; 21 int left = lhas[j] - lhas[x+1]*base[mid-y+1]; 22 if(left ^ right) r = mid-1; 23 else l = mid+1; 24 } 25 return r-y+1; 26 } 27 int main() 28 { 29 base[0] = 1; 30 for(int i=1; i<inf; i++) base[i] = base[i-1]*bas; 31 while(~scanf("%s", s+1)) 32 { 33 s[0] = ‘$‘; 34 int len = strlen(s+1); 35 lhas[len+1] = rhas[0] = 0; 36 for(int i=1; i<=len; i++) 37 { 38 rhas[i] = rhas[i-1]*bas+s[i]-‘a‘; 39 } 40 for(int i=len; i>=1; i--) 41 { 42 lhas[i] = lhas[i+1]*bas+s[i]-‘a‘; 43 } 44 ans = 1; 45 for(int i=1; i<=len; i++) 46 { 47 if(s[i]==s[i+1]) 48 { 49 even = getans(min(2*i, len), i, i+1); 50 ans = max(ans, 2*even); 51 } 52 if(s[i-1]==s[i+1]) 53 { 54 odd = getans(min(2*i-1, len), i-1, i+1); 55 ans = max(ans, 2*odd+1); 56 } 57 } 58 printf("%d\n", ans); 59 } 60 return 0; 61 }
标签:
原文地址:http://www.cnblogs.com/yscc/p/5467398.html