找回密码
 立即注册
首页 业界区 安全 树哈希

树哈希

彼瞄 4 天前
引入

如何 DFS 到某一节点后,利用无序的子树 Hash 值,使得同构的树 Hash 值相同,不同构的 Hash 值尽量不同,且可以 \(O(1)\) 地计算删除部分子树后的 Hash 值?
树结构哈希,简称树哈希,就是解决这类问题的方法。
定义

以某个结点为根的子树的 Hash 值,就是以它的所有儿子为根的子树的 Hash 值构成的多重集的 Hash 值,即

\[H(u)=f(\{H(v)|v \in son(u)\})\]
其中 \(H(u)\) 表示以 \(u\) 为根的子树的 Hash 值,\(f\) 是多重集的 Hash 函数。
以树结构中使用的 Hash 函数为例:

\[H(u)=(c+\sum_{v \in son(u)}f(H(v))) \mod m\]
其中 \(c\) 为常数,一般使用 \(1\) 即可;\(m\) 为模数,一般使用 \(2^{64}\) 自然溢出或大素数;\(f\) 为整数到整数的映射,代码中优先考虑 xorshift。
xorshift

xorshift 是一个伪随机数生成算法,有 \(2^{32}-1,2^{64}-1\) 等周期。代码模版如下:
[code]ull xorshift(ull x) {    x ^= x > 7;    x ^= x > a >> b;        add(a, b);        add(b, a);    }    dfs(1, 0);    sort(hs + 1, hs + n + 1);    cout > n;    for (int i = 1; i > val;    for (int i = 1; i > lc >> rc;        lc = max(lc, 0);        rc = max(rc, 0);    }    h[0][0] = h[1][0] = h[2][0] = h[3][0] = 1001;    dfs(1);    cout > n;    for (int i = 1; i > val;    for (int i = 1; i > lc >> rc;    for (int i = 1; i  v;            if (v == 0) continue;            add(u, v);            add(v, u);        }        dfs(1, 0);        reroot(1, 0);        for (int i = 1; i  fmx[k]) {                smx[k] = fmx[k];                fmx[k] = h;            } else if (h > smx[k])                smx[k] = h;        }        for (int i = 1; i

相关推荐

您需要登录后才可以回帖 登录 | 立即注册