異或雜湊

Yaosicheng124發表於2024-09-02

簡介

我們知道雜湊就是把一個字串轉化為一個數字。但普通的雜湊是有順序的,而如果我們想判斷兩個集合是否相同,就需要使用異或雜湊了。

思路

異或雜湊,就是把每一種值對映到某一個隨機數上,再把它們異或起來。因為異或具有交換律,所以可以比較集合。

但我們怎麼保證異或雜湊的正確性呢?

假設我們隨機的值域為 \([0,2^{64}-1]\),我們來分別考慮每一位;在每一位上,兩個隨機值相等的機率為 \(\frac{1}{2}\),因為總共有 \(4\) 種情況,而只有兩種情況他們相等。所以 \(64\) 位都相等的機率為 \(2^{-64}\)。基本上 \(10^6\) 以內個數都是可以接受的。

程式碼

using ull = unsigned long long;

const int MAXN = 1000001;

int a[MAXN];
ull sum[MAXN];
mt19937_64 rnd(time(0));
map<int, ull> mp;

bool Equiv(int l, int r, int l2, int r2) {
  return (sum[r] ^ sum[l - 1]) == (sum[r2] ^ sum[r2 - 1]);
}

for(int i = 1; i <= n; ++i) {
  cin >> a[i];
  if(!mp.count(a[i])) {
    mp[a[i]] = rnd();
  }
  sum[i] = (sum[i - 1] ^ a[i]);
}