YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

https://www.acwing.com/problem/content/141/

刚学了马拉车算法,找个题目试了一下,然后看题解说这个题目可以用Hash+二,然后就用Hash+二分补了一下,顺便练习一下Hash

如果同马拉车算法来写,直接就套个板子就可以了,但是我在套板子的过程中,如果把数组开到外边,总是出现 segmentation fault,也不知道为啥....

马拉车(140ms):

  

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7;
int p[N];
char s[N];
int manacher(string t){
    vector<int> p(t.size(), 0);
    int id = 0;
    int mx = 0;
    int resCenter = 0;
    int resLen = 0;
    for (int i = 1; i < t.size(); ++i) {
        p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
        while (t[i + p[i]] == t[i - p[i]]) 
            ++p[i];
        if (mx < i + p[i]) {
            id = i;
            mx = i + p[i];
        }
        if (resLen < p[i]) {
            resLen = p[i];
            resCenter = i;
        }
    }
    return resLen-1;
}
int main(){
    int time=0;
    while(cin>>s+1){ 
        if(!strcmp(s+1,"END")) break;
        string t="&#";
        int n=strlen(s+1);
        for(int i=1;i<=n;i++){
            t+=s[i];t+='#';
        }
        printf("Case %d: %d\n",++time,manacher(t));
    }
    return 0;
}
 

二分+Hash(396ms)

  如果要用二分的话,必须将奇偶数分开来二分,为什么呢?假设最长回文串的个数是奇数个,假设为8,当我们用7来判断的时候,结果可能是无回文串,但是如果用5来判断,一定会有回文串的。

还有一个就是Hash的应用,这里要处理两个哈希值,一个是正着,还有一个是倒着处理。然后在check里边,我们用到了滑动窗口。

code:

  

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const ll N=1e6+7;
ll base=233;
char s[N];
ll n;
ll ha1[N],ha2[N],p1[N],p2[N];
ll gethash1(ll x,ll y){
    return ha1[y]-(ha1[x-1]*p1[y-x+1]);
}
ll gethash2(ll x,ll y){
    return ha2[y]-(ha2[x+1]*p2[n-x+y]);
}
ll cnt[N];
ll check(ll x){
    if(x==0||x==1) return 1;
    for(ll l=1,r=x;r<=n;r++,l++){
        if(gethash1(l,l+x/2-1)==gethash2(r,r-x/2+1))
            return 1;
    }
    return 0;
}
int main(){
    int time=0;
    while(cin>>s+1){
        n=strlen(s+1);
        if(!strcmp(s+1,"END")) break;
        p1[0]=1;
        for(ll i=1;i<=n;i++){
            ha1[i]=ha1[i-1]*base+s[i];
            p1[i]=p1[i-1]*base; 
        } 
        p2[n+1]=1;
        for(ll i=n;i>=1;i--){
            ha2[i]=ha2[i+1]*base+s[i];
            p2[i]=p2[i+1]*base; 
        }
        ll pos=0;
        for(ll i=0;i<=n;pos++,i+=2)  cnt[pos]=i;
        ll l=0,r=pos-1;
        ll ans=0;
        while(l<=r){
            ll mid=(l+r)/2;
            if(check(cnt[mid])){
                ans=max(cnt[mid],ans);
                l=mid+1;
            }
            else r=mid-1;
        }
        pos=0;
        for(ll i=1;i<=n;pos++,i+=2) cnt[pos]=i;
        l=0;r=pos-1;
        while(l<=r){
            ll mid=(l+r)/2; 
            if(check(cnt[mid])){
                l=mid+1;
                ans=max(ans,cnt[mid]);
            }
            else r=mid-1;
        }
        printf("Case %d: %lld\n",++time,ans);
    }
    return 0;
} 

 

 

 

posted on 2020-05-18 15:55  Target--fly  阅读(155)  评论(0编辑  收藏  举报