可通过比较区间字符串Hash值来判断两个字符串是否相等:
base类似于进制131就可以,用mod来余除或者unsigned long long 自动余除.
区间Hash值计算 prea[l~r]=prea[r]-prea[l-1]*pre[r-l+1]. prea代表区间累成加a[i]的结果pre[r-l+1]代表还要乘多少才能让prea[r]和prea[l]同位数;类似十进制乘法。
用Hash来过kmp模板题:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
const int N=1e6+10;
const int mod=1e9+7;
int base=131;
int n,m;
string a,b;
int preb[N];
int pre[N];
int HashA;
void init()
{
HashA=0;
for(int i=1;i<=n;i++)
{
HashA=(HashA*base%mod+a[i])%mod;
}
pre[0]=1;
for(int i=1;i<=m;i++)
{
preb[i]=(preb[i-1]*base%mod+b[i])%mod;
pre[i]=pre[i-1]*base%mod;
}
}
void solve()
{
cin>>n>>a>>m>>b;
a=" "+a;
b=" "+b;
init();
int f=0;
for(int i=1,j=n;j<=m;j++,i++)
{
if((preb[j]-preb[i-1]*pre[j-i+1]%mod+mod)%mod==HashA)
{
if(f++) cout<<" ";
cout<<i-1;
}
}
if(!f)cout<<-1<<" "<<-1<<endl;
}
signed main()
{
IOS
// int _;cin>>_;while(_--)
solve();
return 0;
}
选择一段区间翻转后是否能让这个字符串变成回文串
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
const int N=1e5+10;
const int mod=1e9+7;
int base=131;
int n;
string s;
int prea[N],preb[N],pre[N];
void init()
{
pre[0]=1;
for(int i=1;i<=n;i++)
{
// 正向哈希值
prea[i]=(prea[i-1]*base%mod+(s[i]-'a'))%mod;
// 反向哈希值
preb[n-i+1]=(preb[n-i+2]*base%mod+(s[n-i+1]-'a'))%mod;
// 预处理区间哈希值
pre[i]=(pre[i-1]*base)%mod;
}
}
int getHashA(int l,int r)
{
return (prea[r]-prea[l-1]*pre[r-l+1]%mod+mod)%mod;
}
int getHashB(int l,int r)
{
return (preb[l]-preb[r+1]*pre[r-l+1]%mod+mod)%mod;
}
int getA1(int x)
{
// 反向Hash(1~x)*pre[n-x]+正向Hash(x+1~n)
return (getHashB(1,x)*pre[n-x]%mod+getHashA(x+1,n))%mod;
}
int getB1(int x)
{
// 反向Hash(n~x+1)*pre[x]+正向Hash(1~x)
return (getHashB(x+1,n)*pre[x]%mod+getHashA(1,x))%mod;
}
int getA2(int x)
{
// 正向Hash(1~x-1)*pre[n-x+1] +反向Hash(n~x);
return (getHashA(1,x-1)*pre[n-x+1]%mod+getHashB(x,n))%mod;
}
int getB2(int x)
{
// 正向Hash(x~n)*pre[x-1] + 反向Hash(1~x-1)
return (getHashA(x,n)*pre[x-1]%mod+getHashB(1,x-1))%mod;
}
void solve()
{
cin>>s;
int l=0,r=(int)s.length()-1;
while(l<=r)
{
if(s[l]!=s[r]) break;
l++,r--;
}
if(l>=r)
{
cout<<"1 1"<<endl;
return ;
}
string ss="";
for(int i=l;i<=r;i++) ss+=s[i];
s=ss;
n=s.length();
s=" "+s;
init();
// 左边定住枚举右边
for(int i=2;i<=n;i++)
{
if(getA1(i)==getB1(i))
{
cout<<l+1<<" "<<l+i<<endl;
return;
}
}
// 右边定住枚举左边
for(int i=n-1;i>=1;i--)
{
if(getA2(i)==getB2(i))
{
cout<<l+i<<" "<<r+1<<endl;
return;
}
}
cout<<-1<<" "<<-1<<endl;
}
signed main()
{
IOS
// int _;cin>>_;while(_--)
solve();
return 0;
}
/*
*/