//注意MAXN是最大不同的HASH个数,一般HASHN是MAXN的两倍左右,MAXLEN表示字符串的最大长度 //K表示正确率,越大正确率越高,当时也越费空间,费时间。 //使用前注意初始化hash_init(); //用法参考下面注释程序。 //HashNode里面可以储存很多信息,注意灵活使用。 内存如果可能溢出可修改使得内存减一半,但是注意乘法溢出。 #define HASHN 1000007 #define MAXN 500000 #define MAXLEN 500500 #define K 2 typedef unsigned long long ull; typedef unsigned int ui; struct HashNode { int next; ull key[K];//关键点 }hashnode[MAXN]; const ull mod[3]={ 2147483647U, 2147483629U, 2147483587U }; const ull seed[3]={ 131U, 10007U, 4243U}; int hashpre[ HASHN ],hashcnt; void hash_init() { hashcnt=0; memset(hashpre,-1,sizeof(hashpre)); } bool hash_find(ull key[K]) { int hashkey=0; for(int i=0;i<K;i++) hashkey += (key[i])%HASHN; hashkey %= HASHN; ull nkey[K]; for(int p=hashpre[hashkey];p!=-1;p=hashnode[p].next) { for(int i=0;i<K;i++) nkey[i] = hashnode[p].key[i]; bool nsign=0; for(int i=0;i<K;i++) { if(key[i] != nkey[i]) { nsign=1; break; } } if(nsign==0) return true; } return false; } void hash_insert(ull key[K]) { int hashkey=0; for(int i=0;i<K;i++) hashkey += (key[i])%HASHN; hashkey %= HASHN; if( hash_find(key) ) return ;//hash表中已经存在 //不存在使用头插入法,插入新节点。 for(int i=0;i<K;i++) hashnode[hashcnt].key[i] = key[i]; hashnode[hashcnt].next = hashpre[hashkey]; hashpre[ hashkey ] = hashcnt++; } void hash_getkey(char *str,int len,ull key[K]) { ull tmp=1; for(int i=0;i<K;i++) { key[i] = 0; tmp = 1; for(int j=0;j<len;j++) { key[i] = ( key[i]+tmp*str[j] )%mod[i]; tmp *= seed[i]; tmp %= mod[i]; } } return ; } void hash_insert(char *str,int len) { ull key[K]; hash_getkey(str,len,key); hash_insert(key); } bool hash_find(char *str,int len) { ull key[K]; hash_getkey(str,len,key); return hash_find(key); } void hash_getpow(int len,ull hashpow[][MAXLEN]) { ull tmp=1; for(int i=0;i<K;i++) { tmp=1; for(int j=0;j<len;j++) { hashpow[i][j] = tmp; tmp *= seed[i]; tmp %= mod[i]; } } } void hash_getsuffix(char *str,int len,ull hashsuf[][MAXLEN]) { ull tmp=1; for(int i=0;i<K;i++) { tmp=1; for(int j=0;j<len;j++) { hashsuf[i][j] = (tmp*str[j])%mod[i]; tmp *= seed[i]; tmp %= mod[i]; } hashsuf[i][len]=0; for(int j=len-1;j>=0;j--) { hashsuf[i][j] += hashsuf[i][j+1]; if( hashsuf[i][j]>=mod[i] ) hashsuf[i][j] -= mod[i]; } } } void hash_getprefix(char *str,int len,ull hashpref[][MAXLEN]) { ull tmp=1; for(int i=0;i<K;i++) { hashpref[i][0] = str[0]; tmp = seed[i]; for(int j=1;j<len;j++) { hashpref[i][j] = hashpref[i][j-1]+(tmp*str[j])%mod[i]; if( hashpref[i][j]>=mod[i] ) hashpref[i][j] -= mod[i]; tmp *= seed[i]; tmp %= mod[i]; } } } /* char str[1001000]; ull hashpow[K][MAXLEN],hashpref[K][MAXLEN],hashsuf[K][MAXLEN]; int main() { int n,m; scanf("%d%d",&n,&m); hash_init();//第一步初始化 for(int i=0;i<n;i++) { scanf("%s",str); int len=strlen(str); hash_insert(str,len);//插入hash表 } hash_getpow(MAXLEN, hashpow);//得到pow for(int i=0;i<m;i++) { scanf("%s",str); int len=strlen(str); int flag=0; hash_getprefix(str, len, hashpref);//得到前缀和 hash_getsuffix(str, len, hashsuf);//得到后缀和 //具体情况,具体操作。 for(int j=0;j<len;j++) { for(int k='a';k<='c';k++) { if(k==str[j]) continue; ull key[K]; for(int p=0;p<K;p++) { key[p] =( (j>0?hashpref[p][j-1]:0) + hashpow[p][j]*k%mod[p]+hashsuf[p][j+1])%mod[p]; while(key[p]>=mod[p]) key[p] -= mod[p]; } if( hash_find(key) ) { flag=1; break; } } if(flag) break; } if(flag) printf("YES "); else printf("NO "); } return 0; } */