散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它经过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫作散列函数,存放记录的数组叫作散列表。node
很简单的例子
给一列数
而后询问这个数字有没有出现过ios
数组跑,对于过大的下标,或者极大值,正确性不能保证
map每次查询\(O(logn)\)
哈希表查询为\(O(1)\)数组
hash函数跳过不说
最简单的就是\((a*key + b) % mod\)
对于hashmap再取一个小的mod数
看例子看例子
给一列数的hash值为数据结构
54 43 42 22
假定取小mod=11函数
10 10 9 0
而后建图
0 9 10
22 42 43
54spa
而后像临接表同样存储
例如查询43时code
for(int i = head[43 % mod]; i; i = edge[i].nxt){ if(edge[i].val == 43) return 1; }
就完了,确实比map快好多
开O2以后差距不大get
#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; }