POJ - 3974 Palindrome(二分+哈希/马拉车)
生活随笔
收集整理的這篇文章主要介紹了
POJ - 3974 Palindrome(二分+哈希/马拉车)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一個字符串,求字符串中最長的回文子串,這個字串可以包含主串本身
題目分析:這個題就是之前徐州網絡賽的那個回文題目的弱化版。。那個題目正解是要用回文自動機,但我不會,當時搞了兩天終于還是用哈希+二分+動態規劃亂搞出來了,這個題目的話更直接,直接問了最長的回文子串的長度,所以連動態規劃也用不到了,直接把上次那個題目的套路搬過來就行了
處理回文串用馬拉車算法比較好,但我不會,也沒必要學了,用二分和哈希,分情況亂搞一下就出來了(太懶了orz
還有回文自動機也是,現在一個自動機也不會,下午打算去學學AC自動機,好像是最簡單的自動機了?
?2019.11.10更新:
學會了馬拉車來回顧一下這給題目,不得不被馬拉車的精妙設計和時間復雜度所驚艷,比二分和哈希的時間復雜度小了5倍還要多,而且代碼寫起來也簡單多了,在下面貼一下代碼
代碼:
二分+哈希
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef unsigned long long ull;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e6+100;string s;int n;ull hash1[N],hash2[N];ull f[N];void Hash() {hash1[0]=hash2[n+1]=0;f[0]=1;for(int i=1;i<=n;i++){hash1[i]=hash1[i-1]*131+s[i]-'a';f[i]=f[i-1]*131;}for(int i=n;i>=1;i--)hash2[i]=hash2[i+1]*131+s[i]-'a'; }ull gethash1(int l,int r) {return hash1[r]-hash1[l-1]*f[r-l+1]; }ull gethash2(int l,int r) {return hash2[l]-hash2[r+1]*f[r-l+1]; }bool check(int pos,int len,bool state) {int l,r;if(state)//odd{l=pos-len;r=pos+len;}else//even{l=pos-len;r=pos+len+1;}if(l<=0||r>n)return false;ull a=gethash1(l,r);ull b=gethash2(l,r);return a==b; }int main() { // freopen("input.txt","r",stdin);int kase=0;while(cin>>s&&s!="END"){n=s.size();s=" "+s;Hash();int ans=0;for(int i=1;i<=n;i++)//odd{int l=0,r=n;int len=0;while(l<=r){int mid=l+r>>1;if(check(i,mid,true)){len=mid;l=mid+1;}elser=mid-1;}ans=max(ans,2*len+1);}for(int i=1;i<n;i++)//even{int l=0,r=n;int len=0;while(l<=r){int mid=l+r>>1;if(check(i,mid,false)){len=mid;l=mid+1;}elser=mid-1;}ans=max(ans,2*(len+1));}printf("Case %d: %d\n",++kase,ans);}return 0; }馬拉車:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e6+100;char s[N*2];char str[N*2];int p[N*2];int Manacher() {int k=0;s[k++]='!';for(int i=0;str[i];i++){s[k++]='#';s[k++]=str[i];}s[k++]='#';s[k]=0;int ans=0;p[0]=1;int id=0,mmax=0;for(int i=1;i<k;i++){if(i<mmax)p[i]=min(mmax-i,p[2*id-i]);elsep[i]=1;while(s[i-p[i]]==s[i+p[i]])p[i]++;if(i+p[i]>mmax){mmax=i+p[i];id=i;}ans=max(ans,p[i]-1);}return ans; } int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int kase=0;while(scanf("%s",str)!=EOF&&str[0]!='E')printf("Case %d: %d\n",++kase,Manacher());return 0; }?
總結
以上是生活随笔為你收集整理的POJ - 3974 Palindrome(二分+哈希/马拉车)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 126B Pa
- 下一篇: HDU - 2222 Keywords