ACwing 哈希算法入门:

哈希算法:

将字符串映射为数字形式,十分巧妙,一般运用为进制数,进制据前人经验,一般为131,1331时重复率很低,由于字符串的数字和会很大,所以一般为了方便,一般定义为unsigned long long,爆掉时,即为对 2^64 取模,可以对于任意子序列的值进行映射为数字进而进行判断

入门题目链接:

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
const int maxn=1e6+5;
const int base=131;
char s[maxn];
ull has[maxn],p[maxn];
ull get(ull l, ull r)
{
    return has[r]-has[l-1]*p[r-l+1];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>s+1;
    p[0]=1;
    int n=strlen(s+1);
    for(int i=1;i<=n;i++)
    {
        has[i]=has[i-1]*base+s[i]-'a'+1;
        p[i]=p[i-1]*base;
    }
    cin>>t;
    while(t--)
    {
        ull l1,r1,l2,r2;
        cin>>l1>>r1>>l2>>r2;

        if(get(l1,r1)==get(l2,r2))
        {
            cout<<"Yes"<<endl;
        }
        else
        {
            cout<<"No"<<endl;
        }
    }
}

回文子串的最大长度:

题解:

首先处理字符串,在字符串中加入特殊字符,例如 #,让字符串变成奇数,方便处理,求出字符串的正逆哈希,枚举中点,二分长度,求出枚举中的回文串的最长覆盖长度,在处理答案,枚举最大值

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
const int maxn=2e6+5;
const int base=131;
char s[maxn];
ull hl[maxn],p[maxn],hr[maxn];
int n;
ull get(ull h[],int l, int r)
{
    return h[r]-h[l-1]*p[r-l+1];
}
int lower(int l,int r,int i)
{
    while(l<r)
    {
        int mid=l+r+1>>1;
        if(get(hl,i-mid,i-1)!=get(hr,n-(mid+i)+1,n-(1+i)+1))
        {
            r=mid-1;

        }
        else
        {
            l=mid;
        }
    }
    return l;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t=0;
    while(cin>>s+1)
    {

        if(strcmp(s+1,"END")==0)
            break;
        n=strlen(s+1);
        n*=2;
        for(int i=n; i>0; i-=2)
        {
            s[i]=s[i/2];
            s[i-1]='z'+1;
        }
        p[0]=1;
        for(int i=1,j=n; i<=n; i++,j--)
        {
            hl[i]=hl[i-1]*base+s[i]-'a'+1;
            hr[i]=hr[i-1]*base+s[j]-'a'+1;
            p[i]=p[i-1]*base;
        }
        int res=0,ans;
        for(int i=1; i<=n; i++)
        {
            int l=0,r=min(i-1,n-i);
            ans=lower(l,r,i);
            if(s[i-ans]<='z')
            {
                res=max(res,ans+1);
            }
            else
            {
                res=max(res,ans);
            }

        }
        cout<<"Case"<<' '<<++t<<":"<<' '<<res<<endl;
    }

}

HDU: Oulipo

传送门:

哈希和kmp的模板题,但这里用哈希写,哈希写起来,很暴力,很舒服

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
const int maxn=1e6+5;
const int base=131;
char s[maxn],str[maxn];
ull ha[maxn],p[maxn];
ull get(int l,int r)
{
    return ha[r]-ha[l-1]*p[r-l+1];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        cin>>str+1;
        cin>>s+1;
        int n=strlen(s+1);
        int m=strlen(str+1);
        ull tem=str[1]-'A'+1;
        for(int i=2; i<=m; i++)
        {
            tem=tem*base+str[i]-'A'+1;
        }
        p[0]=1;
        for(int i=1; i<=n; i++)
        {
            ha[i]=ha[i-1]*base+s[i]-'A'+1;
            p[i]=p[i-1]*base;
        }
        int ans=0;
        for(int i=1; i+m-1<=n; i++)
        {
            if(tem==get(i,i+m-1))
                ans++;
        }
        cout<<ans<<endl;
    }

}
发布了254 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/104428249
今日推荐