• loj537


    另一道hash题

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    const LL m1 = 999973, m2 = 1000000000 + 9;
    
    char s[5000005];
    
    LL k, tot, ans;
    
    LL h[m1 + 5], h1[5000005], h2[5000005];
    
    struct hash_table
    {
        LL cnt, next;
        string s;
    }a[5000005];
    
    void add(LL k1, string s)
    {
        a[tot].s = s;
        a[tot].cnt = 1;
        a[tot].next = h[k1];
        h[k1] = tot++;
    }
    
    void hash(LL k1, string s)
    {
        for (LL i = h[k1]; ~i; i = a[i].next)
        {
            if (a[i].s == s)
            {
                a[i].cnt++;
                ans = max(ans, a[i].cnt);
                return;
            } 
        }
        add(k1, s);
    }
    
    LL ksm(LL a, LL b, LL mo)
    {
        LL base = a, ans = 1;
        while (b)
        {
            if (b & 1)
                ans = (ans * base) % mo;
            base = (base * base) % mo;
            b >>= 1;
        }
        return ans;
    }
    
    int main()
    {
    //    freopen("loj12A.in","r",stdin); 
        scanf("%s", s + 1);
        scanf("%lld", &k);
        tot = 0;
        memset(h, -1, sizeof h);
        LL len = strlen(s + 1);
        h1[0] = h2[0] = 0;
        LL t1 = ksm(131, k, m1);
        for (int i = 1; i <= len; i++)
        {
            h1[i] = (h1[i - 1] * 131 + s[i]) % m1;
        }
        string ns = string(s + 1);
        for (int i = 1; i <= len - k + 1; i++)
        {
            LL k1 = (((h1[i + k - 1] - h1[i - 1] * t1) % m1) + m1) % m1;
            hash(k1, ns.substr(i - 1, k).c_str());
        }
        printf("%lld
    ", ans);
        return 0;
    }

    这题主要的坑点在于我们需要hash的字符串的重复可能性极大,因此无论是多么优秀的映射算法都会出现大量冲突,此时我们需要手动使用原始的方式——传字符串来进行判重。

  • 相关阅读:
    数字证书
    数字签名

    共享密钥加密
    公开密钥加密
    迪菲赫尔曼密钥交换
    线性查找
    深度优先搜索
    广度优先搜索
    混合加密
  • 原文地址:https://www.cnblogs.com/yohanlong/p/7805683.html
Copyright © 2020-2023  润新知