1. 程式人生 > 實用技巧 >【字串】字串多項式雜湊

【字串】字串多項式雜湊

struct StringHashing {

    static const int MAXN = 1000005;

    int n;
    int bse[3] = {13, 1331, 2333};
    int mod[3] = {998244353, 1000000007, 1000000009};
    int bsk[MAXN][3], hsh1[MAXN][3], hsh2[MAXN][3];

    void Init(char *s) {
        n = strlen(s + 1);
        for(int t = 0; t < 3; ++t) {
            bsk[0][t] = 1, hsh1[0][t] = 0, hsh2[n + 1][t] = 0;
            for(int i = 1; i <= n; ++i) {
                bsk[i][t] = (1LL * bsk[i - 1][t] * bse[t]) % mod[t];
                hsh1[i][t] = (1LL * hsh1[i - 1][t] * bse[t] + s[i]) % mod[t];
                hsh2[n + 1 - i][t] = (1LL * hsh2[n + 1 - i + 1][t] * bse[t] + s[n + 1 - i]) % mod[t];
            }
        }
    }

    int HashCode1(int L, int R, int t) {
        int res = (hsh1[R][t] - 1LL * hsh1[L - 1][t] * bsk[R - L + 1][t]) % mod[t];
        res += (res < 0) ? mod[t] : 0;
        return res;
    }

    int HashCode2(int L, int R, int t) {
        int res = (hsh2[L][t] - 1LL * hsh2[R + 1][t] * bsk[R - L + 1][t]) % mod[t];
        res += (res < 0) ? mod[t] : 0;
        return res;
    }

    bool isEqual(int L1, int R1, int L2, int R2) {
        if(L1 < 1 || R1 > n || L2 < 1 || R2 > n)
            return 0;
        if(L1 > R1 && L2 > R2)
            return 1;
        for(int t = 0; t < 3; ++t) {
            if(HashCode1(L1, R1, t) != HashCode1(L2, R2, t))
                return 0;
        }
        return 1;
    }

    bool isReverseEqual(int L1, int R1, int L2, int R2) {
        if(L1 < 1 || R1 > n || L2 < 1 || R2 > n)
            return 0;
        if(L1 > R1 && L2 > R2)
            return 1;
        for(int t = 0; t < 3; ++t) {
            if(HashCode1(L1, R1, t) != HashCode2(L2, R2, t))
                return 0;
        }
        return 1;
    }

} sh;