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

矩阵哈希

贺蛟亡 2026-2-11 00:20:26
引入

矩阵哈希,又称二维前缀哈希。联系之前学习过的 字符串哈希,不难得出矩阵哈希的实质:将每个不同的矩阵映射为不同的整数,期望 \(O(1)\) 地比较矩阵是否相同。
对于一个 \(n\) 行 \(m\) 列的矩阵 \(A\),定义它的矩阵 Hash 值为:

\[\sum_{i=1}^{n}\sum_{j=1}^{m}A_{i,j} \ p_x^{n-i}p_y^{m-j}\]
类似于二维前缀和的推导过程,我们得出以下两条矩阵哈希的核心结论:

  • 点 \((i, j)\) 的矩阵前缀 Hash 值的计算公式为:

\[H(i,j) = H(i-1,j)p_x + H(i,j-1)p_y - H(i-1,j-1)p_x p_y + a_{i,j}\]

解释: 如上图,蓝色的矩形右下角为 \(H(i,j-1)\),绿色的矩形右下角为 \(H(i,j-1)\),它们重合部分的紫色矩形右下角为 \(H(i-1,j-1)\)。根据容斥原理,紫色矩形被减了两次。

  • 一个 \((l_x, l_y)\) 到 \((r_x, r_y)\) 的子矩阵的 Hash 值为:

\[H(r_x,r_y)-H(l_x-1,r_y)p_x^{r_x-l_x+1}-H(r_x,l_y-1)p_y^{r_y-l_y+1}+H(r_x-1)(r_y-1)p_x^{r_x-l_x+1}p_y^{r_y-l_y+1}\]

解释: 如上图,紫色的矩形右下角为 \(H(r_x,l_y-1)\),绿色的矩形右下角为 \(H(l_x-1,r_y)\),它们重合部分的黄色矩形右下角为 \(H(l_x-1,l_y-1)\)。黑框矩形右下角为 \(H(r_x-1,r_y-1)\)。根据容斥原理,黄色矩形被减了两次。依然是容斥原理。
其中,\(p_x, p_y\) 是两个不相等却相近的质数。如果手动取模 \(mod\) 要保证取同一个值。
例题

Matrix Matcher

问题:\(T\) 组数据,每组数据给定一个 \(N\times M\) 的 \(A\) 矩阵和一个 \(X\times Y\) 的 \(B\) 矩阵求 \(B\) 矩阵在 \(A\) 矩阵中出现的次数。
[code]#include using namespace std;typedef unsigned long long ull;const int N = 1e3 + 8, px = 131, py = 137;int n, m, x, y, ans, T;ull pxpow[N], pypow[N], ahs[N][N], bhs[N][N];ull geths(ull h[][N], int lx, int ly, int rx, int ry) {    return h[rx][ry] - h[lx - 1][ry] * pxpow[rx - lx + 1] - h[rx][ly - 1] * pypow[ry - ly + 1]    + h[lx - 1][ly - 1] * pxpow[rx - lx + 1] * pypow[ry - ly + 1];}int main() {    pxpow[0] = pypow[0] = 1;    for (int i = 1; i < N; i++) pxpow = pxpow[i - 1] * px, pypow = pypow[i - 1] * py;    cin >> T;    while (T--) {        cin >> n >> m;        for (int i = 1; i  c;                ahs[j] = ahs[i - 1][j] * px + ahs[j - 1] * py - ahs[i - 1][j - 1] * px * py + c;            }        cin >> x >> y;        for (int i = 1; i  c;                bhs[j] = bhs[i - 1][j] * px + bhs[j - 1] * py - bhs[i - 1][j - 1] * px * py + c;            }        ans = 0;        for (int i = 1; i  m;    for (int i = 1; i  a[j];    for (int i = 1; i  1;                if (check(i - mid + 1, j - mid + 1, i + mid, j + mid)) l = mid;                else r = mid - 1;            }            ans += l;        }    cout > n;    for (int i = 1; i  x;            ahs[j] = ahs[i - 1][j] * px + ahs[j - 1] * py - ahs[i - 1][j - 1] * px * py + x;        }    for (int i = 1; i  x;            bhs[j] = bhs[i - 1][j] * px + bhs[j - 1] * py - bhs[i - 1][j - 1] * px * py + x;        }    for (int k = 1; k

相关推荐

7 天前

举报

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