[51nod] 1088 最长回文子串 #Hash+二分

1088 最长回文子串

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
 
回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。
输入一个字符串Str,输出Str里最长回文子串的长度。
 
Input
输入Str(Str的长度 <= 1000)
Output
输出最长回文子串的长度L。
Input示例
daabaac
Output示例
5
Analysis分析
Hash解决
具体措施:用秦九韶算法做一个可以用前缀和计算字符串哈希码的hash,然后枚举中点,二分回文字串的长度qwq
具体看代码qwq
 
Code代码
 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<cstring>
 4 #define maxn 421357
 5 #define base 21707
 6 #define ULL unsigned long long
 7 using namespace std;
 8 
 9 ULL stad[maxn],anti[maxn];
10 
11 int n,ans = 1,lens; char s[maxn];
12 
13 ULL Pow(ULL x,int k){
14     if(!k) return 1;
15     if(k == 1) return x;
16     ULL b = 1;
17     while(k){
18         if(k&1) b = b*x;
19         x = x*x;
20         k >>= 1;
21     }return b;
22 }
23 
24 ULL getcode(int L,int R){
25     if(!L) return stad[R];
26     else return stad[R]-stad[L-1]*Pow(base,R-L+1);
27 }
28 
29 ULL getanti(int L,int R){
30     if(R == n) return anti[L];
31     else return anti[L]-anti[R+1]*Pow(base,R-L+1);
32 }
33 
34 int find(int pos){
35     int L = 0,R = min(lens-1-pos,pos),mid;
36     while(L < R){
37         mid = (L+R+1)/2;
38 //        printf("Checking... [%d , %d]\n",pos-mid,pos+mid);
39 //        ULL cntcode = (getanti(pos+1,pos+mid)*base+s[pos])*Pow(base,mid)+getcode(pos+1,pos+mid);
40         if(getcode(pos-mid,pos-1) == getanti(pos+1,pos+mid)) L = mid;
41         else R = mid-1;
42     }return L*2+1;
43 }
44 
45 int exfind(int pos){
46     if(pos == lens-1) return 0;
47     int L = 0,R = min(lens-1-pos,pos+1),mid;
48     while(L < R){
49         mid = (L+R+1)/2;
50 //        printf("Checking... [%d , %d]\n",pos-mid,pos+mid);
51 //        ULL cntcode = (getanti(pos+1,pos+mid)*base+s[pos])*Pow(base,mid)+getcode(pos+1,pos+mid);
52         if(getcode(pos-mid+1,pos) == getanti(pos+1,pos+mid)) L = mid;
53         else R = mid-1;
54     }return L*2;
55 }
56 
57 int main(){
58     scanf("%s",s);
59     lens = strlen(s);
60     
61     ULL cntcode = 0;
62     for(int i = 0;i < lens;i++)
63         cntcode = cntcode*base+s[i],
64         stad[i] = cntcode;
65         
66     cntcode = 0;
67     for(int i = lens-1;i >= 0;i--)
68         cntcode = cntcode*base+s[i],
69         anti[i] = cntcode;
70         
71     for(int pos = 0;pos < lens;pos++)
72         ans = max(ans,find(pos)),
73         ans = max(ans,exfind(pos));
74     cout << ans;
75     
76     return 0;
77 }
秦九韶Hash

 

posted @ 2017-11-05 15:36  Leviaton  阅读(823)  评论(0编辑  收藏  举报