F02【模板】字符串哈希
题目:给定一个字符串,多次询问两个区间的子串是否相同。
把字符串的所有前缀映射为多项式整数:h[i]=h[i-1]*B+s[i]; b[i]=b[i-1]*B;
由前缀哈希值求区间哈希值:h[r]-h[l-1]*b[r-l+1];
// 字符串哈希 O(n) #include<bits/stdc++.h> using namespace std; #define ull unsigned long long const int N=1000010,B=131; int n,m; char s[N]; ull h[N],b[N]; //h[i]存s前缀哈希值,b[i]存B的i次幂 ull get(int l,int r){ //区间哈希值 return h[r]-h[l-1]*b[r-l+1]; //h[r]-h[l-1]*B^(r-l+1) } int main(){ cin>>n>>m; scanf("%s",s+1); h[0]=0,b[0]=1; for(int i=1; i<=n; i++){ h[i]=h[i-1]*B+s[i]; //h[abcde]=a*B^4+b*B^3+c*B^2+d*B^1+e b[i]=b[i-1]*B; //b[i]=B^i } while(m--){ int a,b,c,d; cin>>a>>b>>c>>d; if(get(a,b)==get(c,d)) puts("Yes"); else puts("No"); } return 0; }
题目:给定 N 个字符串,求 N 个字符串中共有多少个不同的字符串。
把每个字符串映射为哈希值:h=h*B+s[i];
排序去重即可。
// 字符串哈希 O(nm) #include<bits/stdc++.h> #define ull unsigned long long using namespace std; const int N=10010,B=131; int n; char s[N]; ull h[N]; ull get(char *s){ //s的哈希值 int n=strlen(s+1); ull h=0; for(int i=1;i<=n;i++) h=h*B+s[i]; return h; } int main(){ cin>>n; for(int i=1; i<=n; i++){ scanf("%s",s+1); h[i]=get(s); } sort(h+1,h+n+1); cout<<unique(h+1,h+n+1)-h-1; return 0; }
// 字符串哈希 O(nm) #include<bits/stdc++.h> #define ull unsigned long long using namespace std; const int N=1000010; ull B=131,M=1e9+7; int n; char s[N]; ull h[N]; ull get(char *s){ int m=strlen(s+1); ull f=0; for(int i=1; i<=m; i++) f=(f*B+s[i])%M; for(int i=1; i<=m; i++) f=(f*B+s[i]); return f; } int main(){ cin>>n; for(int i=1; i<=n; i++){ scanf("%s",s+1); h[i]=get(s); } sort(h+1,h+n+1); int cnt=unique(h+1,h+n+1)-h-1; cout<<cnt; return 0; }
字符串哈希 - OI Wiki
20241116_字符串/哈希 - 题单 - 洛谷 | 计算机科学教育新生态
浙公网安备 33010602011771号