博客
关于我
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/

    你可能感兴趣的文章
    opencv保存图片路径包含中文乱码解决方案
    查看>>
    opencv图像分割2-GMM
    查看>>
    OpenCV:概念、历史、应用场景示例、核心模块、安装配置
    查看>>
    Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
    查看>>
    Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
    查看>>
    openlayers:圆孔相机根据卫星经度、纬度、高度、半径比例推算绘制地面的拍摄的区域
    查看>>
    OpenMCU(一):STM32F407 FreeRTOS移植
    查看>>
    OpenMMLab | 【全网首发】Llama 3 微调项目实践与教程(XTuner 版)
    查看>>
    OpenMMLab | 面向多样应用需求,书生·浦语2.5开源超轻量、高性能多种参数版本
    查看>>
    OpenPPL PPQ量化(4):计算图的切分和调度 源码剖析
    查看>>
    OpenPPL PPQ量化(5):执行引擎 源码剖析
    查看>>
    Openresty框架入门详解
    查看>>
    OpenResty(2):OpenResty开发环境搭建
    查看>>
    openshift搭建Istio企业级实战
    查看>>
    Openstack 之 网络设置静态IP地址
    查看>>
    OpenStack 网络服务Neutron详解
    查看>>
    Openstack(两控制节点+四计算节点)-1
    查看>>
    Openstack企业级云计算实战第二、三期培训即将开始
    查看>>
    OpenStack安装部署实战
    查看>>
    OpenStack的基本概念与架构详解
    查看>>