zoukankan      html  css  js  c++  java
  • Gym

    Gym - 102470J Stamming Aliens 字符串哈希

    题意

    给出一个字符串,寻找最长的子串,使得这个子串的出现次数不少于(m) 次,且输出这个子串最后一次出现的位置。若有多个子串符合条件,则找出最右边的子串。

    若没有,输出"none"

    [m leq |s| leq 40000 ]

    分析

    此题显然具有二分性质,寻找子串也可以哈希做。对每个后缀哈希,二分长度,枚举所有长度为(len) 的子串,对哈希值排序,如果出现同样的(m) 次,(return quad true)

    当然此题也可以SA做,GYM上的时限是1s,必须SA,HDU的原题是5s

    代码

    const ull P = 13331;
    ull H[maxn], Pow[maxn];
    ull Hash[maxn];
    int rak[maxn];
    char ss[maxn];
    
    int n, m, pos;
    
    bool cmp(int a, int b) {
        if (Hash[a] < Hash[b]) return true;
        if (a < b && Hash[a] == Hash[b]) return true;
        return false;
    }
    
    bool check(int len) {
        int c = -1;
        pos = -1;
        for (int i = 0; i <= n - len; i++) {
            rak[i] = i;
            Hash[i] = H[i] - H[i + len] * Pow[len];
        }
        sort(rak, rak + n - len + 1, cmp);
        for (int i = 0; i <= n - len; i++) {
            if (!i || Hash[rak[i]] != Hash[rak[i - 1]]) c = 0;
            if (++c >= m) pos = max(pos, rak[i]);
        }
        return pos >= 0;
    }
    
    int main() {
        Pow[0] = 1;
        for (int i = 1; i <= maxn - 3; i++) Pow[i] = Pow[i - 1] * P;
        while (scanf("%d", &m)) {
            if (!m) break;
            scanf("%s", ss);
            n = strlen(ss);
            H[n] = 0;
            for (int i = n - 1; i >= 0; i--) H[i] = H[i + 1] * P + (ull)(ss[i] - 'a');
            if (!check(1)) {
                puts("none");
                continue;
            }
            int l = 1, r = n;
            while (l < r) {
                int mid = l + r + 1 >> 1;
                if (check(mid)) l = mid;
                else r = mid - 1;
            }
            check(l);
            printf("%d %d
    ", l, pos);
        }
    }
    
    
  • 相关阅读:
    洛谷P2158 [SDOI2008]仪仗队 欧拉函数的应用
    leetcode 130. 被围绕的区域 DFS
    TediousLee CodeForces
    AccurateLee双指针+贪心+字符串
    leetcode80. 删除排序数组中的重复项 II
    CHFDORA:哆啦 A 梦
    cdq分治浅谈
    leetcode面试题64. 求1+2+…+n
    leetcode84. 柱状图中最大的矩形
    leetcode874. 模拟行走机器人
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13546733.html
Copyright © 2011-2022 走看看