Skip to content

Commit

Permalink
omg is a hash struct festival ?
Browse files Browse the repository at this point in the history
  • Loading branch information
iagorrr committed Mar 27, 2024
1 parent 70f48b1 commit eb81c9d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 40 deletions.
39 changes: 0 additions & 39 deletions algorithms/data-structures/big-big-hash.cpp

This file was deleted.

1 change: 0 additions & 1 deletion algorithms/data-structures/big-big-hash.tex

This file was deleted.

41 changes: 41 additions & 0 deletions algorithms/strings/hash-big-mod.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
typedef uint64_t ull;
struct H {
ull x; H(ull x=0) : x(x) {}
H operator+(H o) { return x + o.x + (x + o.x < x); }
H operator-(H o) { return *this + ~o.x; }
H operator*(H o) { auto m = (__uint128_t)x * o.x;
return H((ull)m) + (ull)(m >> 64); }
ull get() const { return x + !~x; }
bool operator==(H o) const { return get() == o.get(); }
bool operator<(H o) const { return get() < o.get(); }
};
static const H C = (long long)1e11+3; // (order ~ 3e9; random also ok)

struct Hash {
int n;
vector<H> ha, pw;
Hash(string& str) : n(str.size()), ha((int)str.size()+1), pw(ha) {
pw[0] = 1;
for (int i = 0; i < (int)str.size(); i++)
ha[i+1] = ha[i] * C + str[i],
pw[i+1] = pw[i] * C;
}
H query(int a, int b) { // hash [a, b]
b++;
return ha[b] - ha[a] * pw[b - a];
}
};

vector<H> getHashes(string& str, int length) {
if ((int)str.size() < length) return {};
H h = 0, pw = 1;
for (int i = 0; i < length; i++)
h = h * C + str[i], pw = pw * C;
vector<H> ret = {h};
for (int i = length; i < (int)str.size(); i++)
ret.push_back(h = h * C + str[i] - pw * str[i-length]);
return ret;
}

H hashString(string& s){H h{}; for(char c:s) h=h*C+c;return h;}

6 changes: 6 additions & 0 deletions algorithms/strings/hash-big-mod.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
\subsection{Hash Interal mod $2^{64}-1$}

Arithmetic mod $2^{64}-1$. 2x slower than mod $2^{64}$ and more code, but works on evil test data (e.g. Thue-Morse, where ABBA... and BAAB... of length $2^{10}$ hash the same mod $2^{64}$).

"typedef ull H;" instead if you think test data is random.

40 changes: 40 additions & 0 deletions algorithms/strings/hash-ull.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using ull = unsigned long long;

const int MAXN(1'000'000);

const ull P = 31;
ull p[MAXN + 1];
void precompute() {
p[0] = 1;
for (int i = 1; i <= MAXN; i++)
p[i] = (P * p[i - 1]);
}

struct Hash {
int n;
vector<ull> h;
// vector<ull> hi;
Hash() {}

Hash(const string& s) : n(s.size()), h(n) /*, hi(n) */ {
h[0] = s[0];
for (int i = 1; i < n; i++)
h[i] = (s[i] + h[i - 1] * P);


// hi[n - 1] = s[n - 1];
// for (int i = n - 2; i >= 0; i--)
// hi[i] = (s[i] + hi[i + 1] * P);
}

ull query(int l, int r) {
ull hash = (h[r] - (l ? h[l - 1] * p[r - l + 1] : 0));
return hash;
}

// ull query_inv(int l, int r) {
// ull hash = (hi[l] - (r + 1 < n ? hi[r + 1] * p[r - l + 1] : 0));
// return hash;
// }
};

0 comments on commit eb81c9d

Please sign in to comment.