字符串专题
哈希
好用的哈希模数:
- unsigned long long/long long 自然溢出
- \(2654435769\)(存疑)
- \(1610612741\)(极力推荐)
- \(998244353\),\(10^9+7\)(经典,貌似容易被×)
提供一种 \(N\) 模数哈希的写法:
Luogu P3546
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=a,_i=b;i<=_i;i=-~i)
#define bd(i,a,b) for(int i=a,_i=b;i>=_i;i=~-i)
using namespace std;
const int N=1e6+509,MT=1;
int n,m,f[N],ans,_L;
char s[N];
inline int read(){int x;scanf("%lld",&x);return x;}
inline void write(int x,int F=1)
{
if(F==0) printf("%lld",x);
else if(F==1) printf("%lld\n",x);
else printf("%lld ",x);
}
struct My_Hash
{
int mod=998244353,seed=131;
int p[N],Pw[N];
inline int Hash(int l,int r) {return ((p[r]-p[l-1]*Pw[r-l+1]%mod+mod)%mod);}
inline void Pre()
{
Pw[0]=1;
fd(i,1,n)
{
p[i]=(p[i-1]*seed+s[i])%mod;
Pw[i]=Pw[i-1]*seed%mod;
}
}
inline void Named(int _mod_,int _seed_) {mod=_mod_,seed=_seed_;}
}H[MT+1];
inline bool Check_Diff(int l,int r,int L,int R)
{
int Need=MT>3?MT-1:MT,Sum=0;
fd(i,0,MT)
if(H[i].Hash(l,r)!=H[i].Hash(L,R))
Sum=-~Sum;
if(Sum>Need) return 1;
return 0;
}
inline bool Check_Same(int l,int r,int L,int R)
{
fd(i,0,MT)
if(H[i].Hash(l,r)!=H[i].Hash(L,R))
return 0;
return 1;
}
signed main()
{
#define FJ
#ifndef FJ
freopen("bzoj1066_.in","r",stdin);
freopen("bzoj1066_.out","w",stdout);
#endif
n=read();m=n/2;
scanf("%s",s+1);
H[0].Named(2654435769,131);//存疑(good)
H[1].Named(1610612741,131);//Good
//998244353 1e9+7//貌似容易被×
// 貌似可以(这道题用这种方法可过):
// srand(time(0));
// fd(i,2,MT) H[i].Named((rand()%1000000000)*1000000000+rand()%1000000000,131);
fd(i,0,MT) H[i].Pre();
bd(i,m,0)
{
_L=min(_L+2,m-i);
while(_L>0&&Check_Diff(i+1,i+_L,n-i-_L+1,n-i)) _L--;
if(Check_Same(1,i,n-i+1,n)) ans=max(ans,i+_L);
}
write(ans);
return 0;
}
另一种写法:
P3370 【模板】字符串哈希
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define db(x) cout<<"DEBUG "<<#x<<" = "<<x<<endl;
#define endl '\n'
using namespace std;
//#define SIZE (1<<20)
//char In[SIZE],Out[SIZE],*p1=In,*p2=In,*p3=Out;
//#define getchar() (p1==p2&&(p2=(p1=In)+fread(In,1,SIZE,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
return x*f;
}
template<typename _T>
inline void write(_T x)
{
static _T sta[35];int top=0;
if(x<0) putchar('-'),x=-x;
do{sta[top++]=x%10,x/=10;}while(x);
while(top) putchar(sta[--top]+'0');
}
template<int SIZ>
struct Hash
{
int p=131,pw[SIZ+5],h[SIZ+5],len,Mod=1610612741;
Hash(int _mod_=-1){Mod=(_mod_==-1)?Mod:_mod_;pw[0]=1;fd(i,1,SIZ)pw[i]=pw[i-1]*p%Mod;}
inline void clear(){fd(i,1,len)h[i]=0;len=0;}
inline int to(char c){return((c>='a'&&c<='z')?c-'a':((c>='A'&&c<='Z')?c-'A'+26:c-'0'+52));}
inline void pre(char s[]){len=strlen(s+1);fd(i,1,len) h[i]=(h[i-1]*p%Mod+to(s[i]))%Mod;}
inline int H(int l=1,int r=-1){if(r==-1) r=len;return (h[r]-h[l-1]*pw[r-l+1]%Mod+Mod)%Mod;}
};
const int N=1e6+509,M=1e6+509,mod=998244353;
set<int> f;
int n;
char s[N];
signed main()
{
//#define FJ
#ifdef FJ
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#else
// freopen("A.in","r",stdin);
// freopen("A.out","w",stdout);
#endif
//#define io
#ifdef io
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
#endif
srand(time(0));
const int _mod_=rand()*rand();
Hash<N> has(_mod_);
n=read();
fd(i,1,n)
{
scanf("%s",s+1);
has.pre(s);
f.insert(has.H());
has.clear();
}
printf("%lld",f.size());
return 0;
}
本文来自博客园,作者:whrwlx,转载请注明原文链接:https://www.cnblogs.com/whrwlx/p/18303888