没用的定义
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
问题引入
很简单的例子
给一列数
然后询问这个数字有没有出现过
solution
数组跑,对于过大的下标,或者极大值,正确性不能保证
map每次查询(O(logn))
哈希表查询为(O(1))
HASH MAP
hash函数跳过不说
最简单的就是((a*key + b) % mod)
对于hashmap再取一个小的mod数
看例子看例子
给一列数的hash值为
54 43 42 22
假定取小mod=11
10 10 9 0
然后建图
0 9 10
22 42 43
54
然后像临接表一样存储
例如查询43时
for(int i = head[43 % mod]; i; i = edge[i].nxt){
if(edge[i].val == 43) return 1;
}
就完了,确实比map快好多
开O2之后差距不大
code
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define int long long
using namespace std;
inline int read(){
int x = 0, w = 1;
char ch = getchar();
for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return x * w;
}
const int mod = 23333;
const int ss = 1000010;
struct node{
int nxt, val;
}edge[ss + 5];
int head[ss + 5], tot;
inline void add(int u){
int sol = u % mod;
edge[++tot].val = u;
edge[tot].nxt = head[sol];
head[sol] = tot;
}
inline bool find(int u){
int sol = u % mod;
for(int i = head[sol]; i; i = edge[i].nxt){
if(edge[i].val == u)
return 1;
}
return 0;
}
inline void erase(int u){
head[u % mod] = 0;
}
inline unsigned long long hash(int u){
u *= 233;
u %= mod;
}
signed main(){
int n = read();
for(int i = 1; i <= n; i++){
int x = read();
add(hash(x));
}
int cnt = read();
while(cnt--){
int x = read();
if(find(hash(x))) puts("AC");
else puts("WA");
}
return 0;
}