哈希表的操作: 插入 查找
时间复杂度看成O(1)
eg 运用拉链法 写一个哈希表 把(-1e9,1e9)的数据映射到(0,1e5)上
#include<bits/stdc++.h>
using namespace std;
const int N=100003; N取为 根据题意最大数字个数 后的质数 把所有数(包括正负)映射到[0,N)上
拉链法处理冲突
int h[N],e[N],ne[N],idx; 链表池
h[N]每个元素相当于一个头结点
void insert(int x){
int t=(x%N+N)%N; 考虑负数情况
e[idx]=x;
ne[idx]=h[t];
h[t]=idx++;
}
void find(int x){
int t=(x%N+N)%N;
int i=0;
for(i=h[t];i!=-1;i=ne[i]){ 遍历链表
if(e[i]==x) {
cout<<"Yes"<<endl;
break;
}
}
if(i==-1) cout<<"No"<<endl;
}
int main(){
以下注释求质数
/*for(int i=100000;;i++){
int flag=1;
for(int j=2;j*j<=i;j++){
if(i%j==0){
flag=0;
break;
}
}
if(flag==1){
cout<<i;
break;
}
}*/ 输出值为100003 即100000后的第一个质数是100003 那么模就用100003
memset(h,-1,sizeof(h)); 各个头结点开始指向-1
int n; cin>>n;
while(n--){
string a;
cin>>a;
if(a=="I"){
int x;
cin>>x;
insert(x);
}
if(a=="Q"){
int x; cin>>x;
find(x);
}
}
}
字符串前缀哈希法 用于快速判断两个字符串是否相等
类似前缀和 存字符串的数组下标要从1开始
只需一个权值数组p 位权设为P131
每个总字符串都有一个前缀哈希值数组hi 可以根据下标框定范围 求范围内字符串的哈希值
前缀哈希值数组unsigned long long 相当于模2^64
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
typedef unsigned long long ULL;
char str[N];
ULL p[N],h[N];
int P=131;
ULL get_hash(int l,int r){ 从1开始的下标
return h[r]-h[l-1]*p[r-l+1];
}
int main(){
int n,m;
cin>>n>>m;
scanf("%s",str+1);
p[0]=1;
for(int i=1;i<=n;i++){ 从1开始
h[i]=P*h[i-1]+str[i];
p[i]=p[i-1]*P;
}
while(m--){
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
if(get_hash(l1,r1)==get_hash(l2,r2)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}