前言
还在为不想写双哈希又怕哈希冲突挂掉发愁吗?
来这里,满足你的一切梦想!
哈希还有模板?
其实就是把相关的函数和数组打包到一个结构体里
但是针心方便啊!!!
如果想双哈希的话,定义一个h2就好啦
极其方便,避免各种数组冲突、复制数组没改干净等烦恼
甚至还可以有这样的惊天n重哈希!
这能卡掉我给您跪下
(复制的话点个赞呗亲awa)
11哈希
int key[12]={0,131,133,107,173,1091,31,131,1331,11,257,277};
int mod[12]={0,1000000021,1000000033,1000000087,100000081,1000000123,1000000447,1000000349,1000000513,100000471,1000000607,10000723};
int p[N],ans;
int jd[N];
int main(){
// printf("%d\n",sizeof(h1)/1024/1024);
for(int i=1;i+m-1<=n;i++) jd[i]=1;
for(int o=1;o<=11;o++){
h1.init(key[o],mod[o]);
h1.gethash();
for(int st=1;st+m-1<=n;st++){
if((st-1)%(5*m)==0) h1.getfresh(st,st+10*m-1);
jd[st]&=h1.calc(st);
//calc这样的函数按题目需要加到结构体里就行拉
}
}
for(int i=1;i+m-1<=n;i++){
if(jd[i]) p[++ans]=i;
}
printf("%d\n",ans);
for(int i=1;i<=ans;i++) printf("%d ",p[i]);
return 0;
}
完整代码
struct Hash{
int key;
ull mod;
ull h1[N][26],h2[N][26],mi[N];
node q1[105],q2[105];
int jd[27],to[27];
void init(int x,ull y){
memset(jd,0,sizeof(jd));
memset(to,0,sizeof(to));
key=x;mod=y;
mi[0]=1;
for(int i=1;i<=max(n,m);i++) mi[i]=mi[i-1]*key%mod;
}
void gethash(){
for(int i=1;i<=n;i++){
for(int j=0;j<=25;j++){
h1[i][j]=(h1[i-1][j]*key+(s[i]=='a'+j))%mod;
}
}
for(int i=1;i<=m;i++){
for(int j=0;j<=25;j++){
h2[i][j]=(h2[i-1][j]*key+(t[i]=='a'+j))%mod;
}
}
}
ull Hash1(int l,int r,int k){
//if(k<=4) printf("l=%d r=%d k=%d ans=%llu\n",l,r,k,h1[r][k]-h1[l-1][k]*mi[r-l+1]);
return (h1[r][k]-h1[l-1][k]*mi[r-l+1]%mod+mod)%mod;
}
ull Hash2(int l,int r,int k){
return (h2[r][k]-h2[l-1][k]*mi[r-l+1]%mod+mod)%mod;
}
}h1;