字符串哈希

news/发布时间2024/5/3 23:34:08

1.区域赛银牌:Problem - J - Codeforces

这道题首先覆盖了字符串哈希的基础板子,其次,通过pll add 和mul函数来重新计算区间反转后的hash值,然后再判断回文

字符串哈希的实质的递推求每一项,求区间子串哈希利用前缀和思想

  1 #include <bits/stdc++.h>  //�ص������㰮�ҵĶ���
  2 using namespace std;
  3 #define ll long long
  4 #define pll pair<long, long>
  5 const int MAXN = 1e6 + 5;
  6 
  7 struct StringHash {
  8   int n;           // 字符串长度
  9   char str[MAXN];  // 下标从1开始
 10   const ll Base1 = 29, MOD1 = 1e9 + 7;
 11   const ll Base2 = 131, MOD2 = 1e9 + 9;
 12   ll ha1[MAXN], ha2[MAXN];    // 正着的哈希值
 13   ll rha1[MAXN], rha2[MAXN];  // 反着的哈希值
 14   ll pow1[MAXN], pow2[MAXN];  // Base1和Base2的乘方
 15 
 16   void init() {  // 预处理pow1[]、pow2[]
 17     pow1[0] = pow2[0] = 1;
 18     for (int i = 1; i <= n; i++) {
 19       pow1[i] = pow1[i - 1] * Base1 % MOD1;
 20       pow2[i] = pow2[i - 1] * Base2 % MOD2;
 21     }
 22   }
 23 
 24   void pre() {  // 预处理ha1[]、ha2[]
 25     for (int i = 1; i <= n; i++) {
 26       ha1[i] = (ha1[i - 1] * Base1 + str[i]) % MOD1;
 27       ha2[i] = (ha2[i - 1] * Base2 + str[i]) % MOD2;
 28       rha1[i] = (rha1[i - 1] * Base1 + str[n - i + 1]) % MOD1;
 29       rha2[i] = (rha2[i - 1] * Base2 + str[n - i + 1]) % MOD2;
 30     }
 31   }
 32 
 33   pll get_hash(int l, int r) {  // 求子串str[l...r]正着的哈希值
 34     ll res1 = ((ha1[r] - ha1[l - 1] * pow1[r - l + 1]) % MOD1 + MOD1) % MOD1;
 35     ll res2 = ((ha2[r] - ha2[l - 1] * pow2[r - l + 1]) % MOD2 + MOD2) % MOD2;
 36     return pll(res1, res2);
 37   }
 38 
 39   pll get_rhash(int l, int r) {  // 求子串str[l...r]反着的哈希值
 40     ll res1 =
 41         ((rha1[n - l + 1] - rha1[n - r] * pow1[r - l + 1]) % MOD1 + MOD1) %
 42         MOD1;
 43     ll res2 =
 44         ((rha2[n - l + 1] - rha2[n - r] * pow2[r - l + 1]) % MOD2 + MOD2) %
 45         MOD2;
 46     return pll(res1, res2);
 47   }
 48 
 49   bool IsPalindrome(int l, int r) {  // 判断子串str[l...r]是否是回文串
 50     return get_hash(l, r) == get_rhash(l, r);
 51   }
 52 
 53   pll add(pll a, pll b) {
 54     ll res1 = (a.first + b.first) % MOD1;
 55     ll res2 = (a.second + b.second) % MOD2;
 56     return pll(res1, res2);
 57   }
 58 
 59   pll mul(pll& a, ll k) {  // a *= Base的k次方
 60     ll res1 = a.first * pow1[k] % MOD1;
 61     ll res2 = a.second * pow2[k] % MOD2;
 62     return pll(res1, res2);
 63   }
 64 } solver;
 65 
 66 void solve() {
 67   cin >> solver.str + 1;
 68 
 69   solver.n = strlen(solver.str + 1);
 70   solver.init();
 71   solver.pre();
 72 
 73   int l = 1, r = solver.n;
 74   while (l < r && solver.str[l] == solver.str[r])
 75     l++, r--;  // 去掉两边相同的字符
 76 
 77   if (l >= r) {  // 原串是回文串
 78     cout << "1 1" << endl;
 79     return;
 80   }
 81 
 82   for (int i = l; i <= r; i++) {  // 翻转前缀str[l...i]
 83     auto tmp1 = solver.get_rhash(l, i), tmp2 = solver.get_hash(i + 1, r);
 84     auto res1 = solver.add(solver.mul(tmp1, r - i), tmp2);
 85     auto tmp3 = solver.get_hash(l, i), tmp4 = solver.get_rhash(i + 1, r);
 86     auto res2 = solver.add(solver.mul(tmp4, i - l + 1), tmp3);
 87     if (res1 == res2) {
 88       cout << l << ' ' << i;
 89       return;
 90     }
 91   }
 92 
 93   for (int i = l; i <= r; i++) {  // 反转后缀str[i...r]
 94     auto tmp1 = solver.get_hash(l, i - 1), tmp2 = solver.get_rhash(i, r);
 95     auto res1 = solver.add(solver.mul(tmp1, r - i + 1), tmp2);
 96     auto tmp3 = solver.get_rhash(l, i - 1), tmp4 = solver.get_hash(i, r);
 97     auto res2 = solver.add(solver.mul(tmp4, i - l), tmp3);
 98     if (res1 == res2) {
 99       cout << i << ' ' << r;
100       return;
101     }
102   }
103 
104   cout << "-1 -1";
105 }
106 
107 int main() { solve(); }

 

 

练习: (稍后更新)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/77416244.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

Wpf color rgb combined mutablly

1.Red mixed Green generates Yellow 2.Red mixed Blue is purple 3.Green mixed Blue is Cyan

【Kotlin】委托模式

1 委托模式简介 ​ 委托模式的类图结构如下。​ 对应的 Kotlin 代码如下。 fun main() {var baseImpl = BaseImpl()var baseWrapper = BaseWrapper(baseImpl)baseWrapper.myFun1() // 打印: BaseImpl, myFun1baseWrapper.myFun2() // 打印: BaseImpl, myFun2 }interface …

DjangoRestFramework之DRF初识

一.Web应用两种开发模式 1、前后端不分离模式 也叫前后端混合开发模式, 需要后端写模板语言(DTL), 返回的是HTML页面,比如有BBS项目,图书管理系统。 在前后端不分离的项目中,模板渲染通常是在后端完成的。这种项目结构中,后端负责处理业务逻辑、与数据库交互,并最终生成 H…

Unity组件

二、Mesh网格 1 Mesh Filter Mesh Filter 组件包含对网格的引用。该组件与同一个游戏对象上的 Mesh Renderer 组件配合使用;Mesh Renderer 组件渲染 Mesh Filter 组件引用的网格。用于将网格数据应用到 3D 模型上。它是实现 3D 模型的重要组成部分之一,可以定义模型的形状和结…

最好用的Python IDE,pycharm保姆级安装教程

简介 由于Python语法简单容易入门,并且Python在办公自动化等领域的功能非常强大,所以现在越来越多非IT行业的人也开始学起了Python,要学习和使用一门编程语言,一个好用的IDE是必不可少的,而对于Python来说,最好的IDE无疑是Pycharm。本文就给大家介绍一下如何从零到一来安…

2-58. 实现农作物的重复收割

修改 Crop修改 GridMapManager修改 EventHandler修改 GridMapManager修改 Crop修改 CropDataList_SO项目相关代码 代码仓库:https://gitee.com/nbda1121440/farm-tutorial.git 标签:20240410_1825