日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ - 3974 Palindrome(二分+哈希/马拉车)

發布時間:2024/4/11 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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(二分+哈希/马拉车)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。