1. 程式人生 > 其它 >YbtOJ hash和hash表課堂過關 例2 迴文子串【hash】

YbtOJ hash和hash表課堂過關 例2 迴文子串【hash】

技術標籤:題解hashYbtOJ專項練習題字串hash雜湊YbtOJ題解

題目

在這裡插入圖片描述


思路

這道題首先需要正著hash一次,反著再做一次hash。
其次我們要列舉一個 i i i,向兩邊擴散列舉,擷取一段字串
直接用STL擷取會使時間複雜度變高,
所以使兩段hash字串相減並用正取和反取的兩段比較。
這樣再二分一個擴散的距離mid,
這樣就可以使時間複雜度降低到允許範圍內。

程式碼

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace
std; unsigned long long f[1000010],shang[1000010],xia[1000010]; long long ans=0,js; string s; int main() { cin>>s; while(s!="END") { s=" "+s; long long myc=s.size(); f[0]=1ull,shang[0]=s[0]-97; ans=0,js++; for(long long i=1; i<=myc; ++i) f[i]=f[i-1]*131ull,shang[
i]=shang[i-1]*131ull+(s[i]-97); xia[myc]=0; for(long long i=myc; i>=1; --i) xia[i]=xia[i+1]*131ull+(s[i]-97); for(long long i=1; i<=myc; ++i) { long long l=0,r=myc,mid=0; while(l<=r) { mid=(l+r)>>1; if(i-mid-1<0||i+mid+1>myc) { r=
mid-1; continue; } else if(shang[i]-shang[i-mid-1]*f[mid+1]==xia[i]-xia[i+mid+1]*f[mid+1]) l=mid+1,ans=max(ans,mid*2+1); else r=mid-1; } l=0,r=myc; while(l<=r) { mid=(l+r)>>1; if(i-mid<0||i+mid+1>myc) { r=mid-1; continue; } else if(shang[i]-shang[i-mid]*f[mid]==xia[i+1]-xia[i+1+mid]*f[mid]) l=mid+1,ans=max(ans,mid*2); else r=mid-1; } } printf("Case %lld: %lld\n",js,ans); cin>>s; } return 0; } //abcbabcbabcba abacacbaaaab