哈希算法:
将字符串映射为数字形式,十分巧妙,一般运用为进制数,进制据前人经验,一般为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;
}
}