Hash-字符串哈希(demo


单哈/双哈 Demo, 随机模数

如有任何建议/问题欢迎评论区指出

单:

class Hash {
    static int findprime() {
        std::random_device rd;
        std::mt19937 gen(rd());
        int n = gen() % 900000000 + 100000000;
        if (n % 2 == 0)
            n++;
        while (true) {
            bool ok = 1;
            for (int i = 3; i * i <= n; i += 2) {
                if (n % i == 0) {
                    ok = 0;
                    n += 2;
                    break;
                }
            }
            if (ok)
                return n;
        }
    }

    static const int Mod;
    const int B1 = 131;
    const int B2 = 13331;
    std::vector<int> f1, pow1;

public:
    using LL = long long;

    Hash() : f1(1), pow1(1, 1) {}
    Hash(const std::string &s) : f1(1), pow1(1, 1) {
        insert(s);
    }

    // 0-base
    int get(int l, int r) const {
        l++, r++;
        return (f1[r] - (LL)f1[l - 1] * pow1[r - l + 1] % Mod + Mod) % Mod;
    }
    void insert(const std::string &s) {
        int len1 = f1.size(), len2 = s.size();
        f1.resize(len1 + len2);
        pow1.resize(std::max<int>(len1 + len2, pow1.size()));
        for (int i = len1; i < len1 + len2; i++) {
            pow1[i] = (LL)pow1[i - 1] * B1 % Mod;
            f1[i] = ((LL)f1[i - 1] * B1 + s[i - len1]) % Mod;
        }
    }
    void clear() {
        f1.resize(1);
    }
};

const int Hash::Mod = Hash::findprime();

双:

class Hash2 {
    static int findprime() {
        std::random_device rd;
        std::mt19937 gen(rd());
        int n = gen() % 900000000 + 100000000;
        if (n % 2 == 0)
            n++;
        while (true) {
            bool ok = 1;
            for (int i = 3; i * i <= n; i += 2) {
                if (n % i == 0) {
                    ok = 0;
                    n += 2;
                    break;
                }
            }
            if (ok)
                return n;
        }
    }

    static const int Mod;
    const int B1 = 131;
    const int B2 = 13331;
    std::vector<int> f1, f2, pow1, pow2;

public:
    using LL = long long;

    Hash2() : f1(1), f2(1), pow1(1, 1), pow2(1, 1) {}
    Hash2(const std::string &s) : f1(1), f2(1), pow1(1, 1), pow2(1, 1) {
        insert(s);
    }

    // 0-base
    std::pair<int, int> get(int l, int r) {
        l++, r++;
        return {(f1[r] - (LL)f1[l - 1] * pow1[r - l + 1] % Mod + Mod) % Mod,
                (f2[r] - (LL)f2[l - 1] * pow2[r - l + 1] % Mod + Mod) % Mod};
    }
    void insert(const std::string &s) {
        int len1 = f1.size(), len2 = s.size();
        f1.resize(len1 + len2), f2.resize(len1 + len2);
        pow1.resize(std::max<int>(len1 + len2, pow1.size())), pow2.resize(std::max<int>(len1 + len2, pow1.size()));
        for (int i = len1; i < len1 + len2; i++) {
            pow1[i] = (LL)pow1[i - 1] * B1 % Mod;
            f1[i] = ((LL)f1[i - 1] * B1 + s[i - len1]) % Mod;
            pow2[i] = (LL)pow2[i - 1] * B2 % Mod;
            f2[i] = ((LL)f2[i - 1] * B2 + s[i - len1]) % Mod;
        }
    }
    void clear() {
        f1.resize(1), f2.resize(1);
    }
};

const int Hash2::Mod = Hash2::findprime();
,

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注