洛谷P3370 【模板】字符串哈希

来源:互联网 发布:北京美工工资怎么算 编辑:程序博客网 时间:2024/06/08 06:18

一定要记住HASH链表的高端写法!!!
参考了杨婉倩大佬的写法,原来的自己乱搞版WA了70分……

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define ull unsigned long longconst int base1=1000007,base2=99859,MOD=69847;int cnt=0,len;int head[MOD+2],nxt[10000+5],etot;char s[1505]; struct node{    ull f,s;}val[10000+5];int ha(int from,ull hash1,ull hash2){    for(int i=head[from];i;i=nxt[i])        if(val[i].f==hash1&&val[i].s==hash2) return 0;    val[++etot].f=hash1,val[etot].s=hash2;    nxt[etot]=head[from];    head[from]=etot;    return 1;}void Hash(int len){    ull hash1=1,hash2=1;    for(int i=1;i<=len;i++){        hash1=(hash1+s[i])*base1;        hash2=hash1*base2;    }    cnt+=ha((hash2%MOD+MOD)%MOD,hash1,hash2);}int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++){        scanf("%s",s);        len=strlen(s);        Hash(len);    }    printf("%d",cnt);    return 0;}

ywq大佬的原版

#include<bits/stdc++.h>#define uint unsigned intusing namespace std;const int N = 10000 + 10;const int M = 1500 + 10;const int mod = 10000007;int n,cnt=0;char s[M];struct node{    int pre;    uint hash1,hash2;}stb[N];int num=0,head[mod+3];int link(int from,uint hash1,uint hash2){    for(int i=head[from];i;i=stb[i].pre)        if(stb[i].hash1==hash1&&stb[i].hash2==hash2) return 0;    stb[++num].pre=head[from],stb[num].hash1=hash1,stb[num].hash2=hash2;    head[from]=num;    return 1;}void hash(int len){    uint seed=31,hash1=0;    for(int i=0;i<len;++i) hash1=hash1*seed+s[i];    uint hash2=0;    for(int i=0;i<len;++i){        if(i&1) hash2^=(~((hash2<<11)^s[i]^(hash2>>5)));        else hash2^=((hash2<<7)^s[i]^(hash2>>3));    }    cnt+=link(hash1%mod,hash1,hash2);}int main(){    scanf("%d",&n);    while(n--){        scanf("%s",s);        int len=strlen(s);        hash(len);    }    printf("%d\n",cnt);    return 0;}
原创粉丝点击