拉鍊哈希表

抄的 OI-wiki。

hash_table?

首先要有哈希函數,將一個特定的複雜結構變成一個整數, 當然, 哈希函數不應有隨機性。

然後對於哈希表的值域進行拉鍊, 避免哈希衝突。

如果哈希表的值域大小爲 \(M\), 表內插入了 \(N\) 個元素, 那麼單次查詢的期望複雜度是 \(O(\frac NM)\)(看上去不太靠譜啊)。

比如這題 [USACO12DEC]Running Away From the Barn G 就可以用 hash_table

糊了下代碼:

#include<bits/stdc++.h>

using namespace std;

const int N = 100003;

int n,m,a[30];
int tot, hd[N], nt[N], ky[N][30], p[N];
bool eq(int *x,int *y) {
	for(int i=0;i<m;++i) if(x[i]!=y[i]) return false;
	return true;
}
int has() {
	int res = 0;
	for(int i=0;i<m;++i) res = (res*233ll+a[i])%N;
	return (res%N+N)%N;
}
void ad(int x,int i) {
	nt[++tot]=hd[x], hd[x]=tot;
	memcpy(ky[tot],a,sizeof a);
	p[tot] = i;
}
int get(int pp) {
	int x = has();
	for(int i=hd[x]; i; i=nt[i])
		if(eq(ky[i],a)) return p[i];
	return ad(x,pp), -1;
}

int main()
{
	scanf("%d%d",&n,&m);
	ad(0,0);
	int ans = 0;
	for(int i=1;i<=n;++i) {
		int x; scanf("%d",&x); for(int j=0;j<m;++j) a[j]+=((x>>j)&1);
		if(x&1) for(int j=0;j<m;++j) --a[j];
			int pr = get(i);
		if(pr!=-1) ans = max(ans,i-pr);
	}
	cout << ans;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章