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

    你可能感兴趣的文章
    OAuth2.0_授权服务配置_令牌服务和令牌端点配置_Spring Security OAuth2.0认证授权---springcloud工作笔记143
    查看>>
    OAuth2.0_授权服务配置_客户端详情配置_Spring Security OAuth2.0认证授权---springcloud工作笔记142
    查看>>
    OAuth2.0_授权服务配置_密码模式及其他模式_Spring Security OAuth2.0认证授权---springcloud工作笔记145
    查看>>
    OAuth2.0_授权服务配置_授权码模式_Spring Security OAuth2.0认证授权---springcloud工作笔记144
    查看>>
    OAuth2.0_授权服务配置_资源服务测试_Spring Security OAuth2.0认证授权---springcloud工作笔记146
    查看>>
    OAuth2.0_环境介绍_授权服务和资源服务_Spring Security OAuth2.0认证授权---springcloud工作笔记138
    查看>>
    OAuth2.0_环境搭建_Spring Security OAuth2.0认证授权---springcloud工作笔记139
    查看>>
    oauth2.0协议介绍,核心概念和角色,工作流程,概念和用途
    查看>>
    OAuth2.0四种模式的详解
    查看>>
    OAuth2授权码模式详细流程(一)——站在OAuth2设计者的角度来理解code
    查看>>
    oauth2登录认证之SpringSecurity源码分析
    查看>>
    OAuth2:项目演示-模拟微信授权登录京东
    查看>>
    OA系统多少钱?OA办公系统中的价格选型
    查看>>
    OA系统选型:选择好的工作流引擎
    查看>>
    OA让企业业务流程管理科学有“据”
    查看>>
    OA项目之会议通知(查询&是否参会&反馈详情)
    查看>>
    Vue.js 学习总结(13)—— Vue3 version 计数介绍
    查看>>
    OA项目之我的会议(会议排座&送审)
    查看>>
    OA项目之我的会议(查询)
    查看>>
    OA项目之我的审批(会议查询&会议签字)
    查看>>