1.字符串哈希
题目链接:
代码:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int maxn = 1e5+5;
char s[1505]; int n;
const ull mod = 999999999999999989, base = 233;
ull a[maxn];
ull hashStr(char* s){
int len=strlen(s);
ull res = 0;
for(int i=0; i<len; i++) {res = (res*base+s[i])%mod;}
return res;
}
int main(){
cin>>n;
for(int i=1; i<=n; i++){
scanf("%s",s);
a[i] = hashStr(s);
}
sort(a+1,a+n+1);
int ans = 1;
for(int i=1; i<n; i++) {if(a[i] != a[i+1]) ans++;}
cout<<ans;
}
2.二维哈希
题目:(看下图就知道题目意思了)
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a), (i##i)=(b); i<=(i##i); ++i)
#define ROF(i,a,b) for(int i=(a), (i##i)=(b); i>=(i##i); --i)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
#define ull unsigned long long
// #define int long long
const int N = 2005, b1=131, b2=233;
int n1,m1,n2,m2;
char mp1[N][N], mp2[N][N];
ull h1[N][N], h2[N][N];
ull p1[N], p2[N]; //b1和b2的n次方
ull get1(int x1,int y1,int x2,int y2){
//询问子矩形的hash值
return h1[x2][y2]-h1[x2][y1-1]*p1[y2-y1+1]-h1[x1-1][y2]*p2[x2-x1+1]
+h1[x1-1][y1-1]*p1[y2-y1+1]*p2[x2-x1+1];
}
ull get2(int x1,int y1,int x2,int y2){
return h2[x2][y2]-h2[x2][y1-1]*p1[y2-y1+1]-h2[x1-1][y2]*p2[x2-x1+1]
+h2[x1-1][y1-1]*p1[y2-y1+1]*p2[x2-x1+1];
}
void init(){
p1[0]=p2[0]=1;
FOR(i,1,1000) p1[i]=p1[i-1]*b1;
FOR(i,1,1000) p2[i]=p2[i-1]*b2;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
init();
cin>>n1>>m1>>n2>>m2;
FOR(i,1,n1) cin>>(mp1[i]+1);
FOR(i,1,n2) cin>>(mp2[i]+1);
// get_hash(h1,n1,m1,mp1);
FOR(i,1,n1){
FOR(j,1,m1) h1[i][j]=h1[i][j-1]*b1+mp1[i][j];
}
FOR(i,1,n1){
FOR(j,1,m1) h1[i][j]+=h1[i-1][j]*b2;
}
//get hash of mp2
FOR(i,1,n2){
FOR(j,1,m2) h2[i][j]=h2[i][j-1]*b1+mp2[i][j];
}
FOR(i,1,n2){
FOR(j,1,m2) h2[i][j]+=h2[i-1][j]*b2;
}
int ans = 0;
FOR(i,1,n2) FOR(j,1,m2){
if(i+n1-1>n2 || j+m1-1>m2) continue;
if(h1[n1][m1]==get2(i,j,i+n1-1,j+m1-1)){
ans++;
}
}
cout<<ans;
}