zoukankan      html  css  js  c++  java
  • ACwing 139. 回文子串的最大长度(二分+Hash)

    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
    ",++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
    ",++time,ans);
        }
        return 0;
    } 

     

  • 相关阅读:
    CentOS安装gotop
    oracle 非sys用户创建新用户 授权后 plsql看不到视图
    解决Eclipse+ADT连接夜神模拟器失败问题
    Ext JS v2.3.0 Ext.grid.ColumnModel renderer Record 获取列值
    vi常用快捷键汇总
    外键的变种
    完整性约束
    数据类型2
    数据类型
    表的操作
  • 原文地址:https://www.cnblogs.com/Accepting/p/12911066.html
Copyright © 2011-2022 走看看