博客
关于我
2021牛客寒假第四场 武辰延的字符串(二分+哈希)
阅读量:624 次
发布时间:2019-03-12

本文共 2250 字,大约阅读时间需要 7 分钟。

为了解决这个问题,我们需要找到两个字符串 st,其中 s 的非空前缀连起来能够形成 t 的前缀。具体来说,我们需要统计有多少个 s 的前缀是 t 的前缀。

方法思路

  • 问题分析

    • 我们需要找到 s 的所有前缀,并检查这些前缀是否是 t 的前缀的一部分。
    • 这可以通过预处理 st 的前缀哈希值来高效实现,以减少哈希冲突的概率。
  • 哈希预处理

    • 预处理 st 的前缀哈希值和幂次数组。哈希值用于快速比较两个字符串的前缀是否相同,幂次数组用于计算哈希值。
  • 比较前缀

    • 对于每个可能的前缀长度 k,检查 s 的前 k 个字符的哈希值是否等于 t 的前 k 个字符的哈希值。如果相等,则计数加一。
  • 优化

    • 由于 st 的长度可能不同,我们只需要检查到两者长度较小的那个。
  • 解决代码

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;#define ll long long#define ull unsigned ll#define inf 0x3f3f3f3f#define mod 1e9+7#define base 131#define base2 233ll read() { ll res = 0, flag = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') flag = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { res = (res < 10) + (res < 1) + (ch - '0'); ch = getchar(); } return res * flag;}int main() { string s = read_str(), t = read_str(); int len_s = s.size(), len_t = t.size(); int max_len = min(len_s, len_t); // 预处理哈希和幂次数组 vector
    p(max_len + 2, 1), p2(max_len + 2, 1); vector
    sum1(max_len + 2, 0), sum2(max_len + 2, 0); vector
    pre1(max_len + 2, 0), pre2(max_len + 2, 0); for (int i = 1; i <= max_len; ++i) { p[i] = p[i-1] * base % mod; p2[i] = p2[i-1] * base2 % mod; sum1[i] = (sum1[i-1] * base + s[i-1]) % mod; pre1[i] = (pre1[i-1] * base2 + s[i-1]) % mod; sum2[i] = (sum2[i-1] * base + t[i-1]) % mod; pre2[i] = (pre2[i-1] * base2 + t[i-1]) % mod; } auto get_hash = [](int l, int r, vector
    & a, vector
    & p) { ll hash = (a[r] - a[l-1] * p[r - l + 1]) % mod; if (hash < 0) hash += mod; return hash; }; ll ans = 0; for (int i = 1; i <= max_len; ++i) { if (s[i-1] != t[i-1]) break; int l = 0, r = len_t - i; ll target = get_hash(1, r, sum2, pre2); ll current = 0; int max_r = r; while (r > 0) { int mid = max_r / 2 + 1; if (mid > max_r) break; ll h = get_hash(1, mid, sum1, pre1); if (h == target) { current = mid; l = mid + 1; max_r = mid - 1; } else if (h < target) { max_r = mid - 1; } else { r = mid - 1; } } if (current > 0) ans += current; } cout << ans << endl; return 0;}

    代码解释

  • 读取输入:使用 read() 函数读取字符串 st
  • 预处理哈希数组:计算 st 的前缀哈希值和幂次数组,以便快速比较前缀。
  • 哈希查询函数get_hash 函数用于计算给定范围内的哈希值。
  • 二分查找:对于每个可能的前缀长度 i,使用二分查找确定 s 的前 i 个字符是否是 t 的前缀的一部分。
  • 统计结果:统计满足条件的前缀数量并输出结果。
  • 转载地址:http://frrxz.baihongyu.com/

    你可能感兴趣的文章
    python file
    查看>>
    Python FileDialog获取文件夹路径不是文件
    查看>>
    python filter过滤器的使用_python基础知识分享:zip()、filter函数和reduce如何使用?...
    查看>>
    python flask 请求code 400, message Bad request version
    查看>>
    Python Flink Stateful函数入口上的Kafka键访问
    查看>>
    Python float - str - 浮动怪异
    查看>>
    Python Flower库:分布式任务管理与监控
    查看>>
    Python for 循环和迭代器行为
    查看>>
    Python For循环多次返回
    查看>>
    python frame_python3 selenium自动化 frame表单嵌套的切换方法
    查看>>
    Python ftplib - 指定端口
    查看>>
    Python furl库:一键搞定复杂URL操作
    查看>>
    Python GC 也会关闭文件吗?
    查看>>
    python gen_key.py 报错 提示找不到OpenSSL lib
    查看>>
    python getattrribute_Python学习——面向对象高级之反射
    查看>>
    Python进阶语法:字典推导式
    查看>>
    python gil_Python中GIL的使用详解
    查看>>
    python glob.glob使用
    查看>>
    python glob的安装和使用
    查看>>
    Python google drive API 下载,文件在哪里?
    查看>>