题目传送门

题意

给你三个字符串,问最短同时以这三个字符串为子串的字符串的长度是多少。
s 1 , s 2 , s 3 ≤ 1 0 5 s1,s2,s3≤10^{5} s1,s2,s3≤105

题解

观察题目数据范围,发现应该使要用 O ( ∣ s ∣ ) O(|s|) O(∣s∣) 左右的时间复杂度解决此题。
可以发现显然有一个结论,就是当你确定了三个字符串放置的顺序,那么只需要将三个字符串接起来,然后将相邻两个字符串的最长相同前后缀只取一段即可。
对于这个问题,显然可以用 K M P KMP KMP 实现我就不,但是可以用另一种简单易懂的方式处理子串问题,就是字符串哈希
简述一下字符串哈希的过程:
设 h a x i [ i ] haxi[i] haxi[i] 表示字符串 S S S 前 i i i 位的哈希值,那么哈希公式如下:
h a x i [ i ] = ( h a x i [ i − 1 ] ∗ p + s [ i ] ) % m o haxi[i]=(haxi[i-1]*p+s[i])\%mo haxi[i]=(haxi[i−1]∗p+s[i])%mo
其中, p p p 和 m o mo mo 是两个质数, m o > p mo>p mo>p
如果我们要提取一个子串 s [ l ∼ r ] s[l \sim r] s[l∼r] ,那么公式为:
h a x i [ l ∼ r ] = ( ( h a x i [ r ] − h a x i [ l ] ∗ p r − l + 1 ) % m o + m o ) % m o haxi[l \sim r]=((haxi[r]-haxi[l]*p ^ {r-l+1})\%mo+mo)\%mo haxi[l∼r]=((haxi[r]−haxi[l]∗pr−l+1)%mo+mo)%mo
然后特判一下当前要拼接的两个串是否是对方的字串,如果是的话直接舍弃字串即可。
当然可以使用双哈希减少冲突概率,简单来说就是使用两个 m o mo mo, m o 1 mo1 mo1和 m o 2 mo2 mo2,构造两个哈希数组 ( h a x i 1 , h a x i 2 ) (haxi1,haxi2) (haxi1,haxi2) 。
关于质数的选取可以参考一下这篇博客

CODE

#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const LL MO = 402653189, P = 131;
const int pl[6][3]={{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}}, N = 100005;
//懒得写递归,字符串排列顺序
int ans, len[3], sum;
char s[3][N];
LL haxi[3][N], mi[N];
bool pd(int lens, int lent, int k1, int k2) {if (lens > lent) {for (int i = 1; i <= lens - lent + 1; ++i) {int r = i + lent - 1;if (((haxi[k1][r] - haxi[k1][i - 1] * mi[r - i + 1] % MO) + MO) % MO == haxi[k2][lent]) return 1;}}else {for (int i = 1; i <= lent - lens + 1; ++i) {int r = i + lens - 1;if (((haxi[k2][r] - haxi[k2][i - 1] * mi[r - i + 1] % MO) + MO) % MO == haxi[k1][lens]) return 1;}} return 0;
}//判断是字串的情况
int solve(int lens, int lent, int k1, int k2) {for (int i = min(lens, lent); i; --i) {int l = lens - i + 1;if (((haxi[k1][lens] - haxi[k1][l - 1] * mi[lens - l + 1] % MO) % MO + MO) % MO == haxi[k2][i]) return i;} return 0;
}//找最长相同前后缀
int main() {mi[0] = 1; ans = INF;for (int i = 1; i < N; ++i) mi[i] = mi[i - 1] * P % MO;//预处理幂会更快for (int i = 0; i < 3; ++i) {scanf("%s", s[i] + 1); len[i] = strlen(s[i] + 1); sum += len[i];for (int j = 1; j <= len[i]; ++j) haxi[i][j] = (haxi[i][j - 1] * P + s[i][j]) % MO;//字符串哈希}for (int i = 0; i < 6; ++i) {int res = 0;for (int j = 1; j < 3; ++j) {if (pd(len[pl[i][j]], len[pl[i][j - 1]], pl[i][j], pl[i][j - 1])) {res += min(len[pl[i][j]], len[pl[i][j - 1]]); continue;} res += solve(len[pl[i][j]], len[pl[i][j - 1]], pl[i][j],pl[i][j - 1]);} ans = min(ans, sum - res);} printf("%d\n",ans);return 0;
}

Codeforces 25E Test 题解相关推荐

  1. c语言1106回文数,Codeforces 1106 简要题解

    A题 传送门 读错题还能过样例我给自己点个赞. 题意简述:给一个010101网格SSS,问满足Si,j=Si+1,j+1=Si+1,j−1=Si−1,j−1=Si−1,j+1S_{i,j}=S_{i+ ...

  2. Educational Codeforces Round 95题解

    Educational Codeforces Round 95题解 题目链接 代码链接 A. Buying Torches 题目大意: 你手上现在有一个木棍.有以下两种交换方式: 1.用一个木棍交换x ...

  3. 【Codeforces div3-498】题解

    Codeforces div3-498题解 A. Adjacent Replacements 对于这道题目就比较简单了,如果该数N为奇数,那么经过变换之后不变,如果该数为偶数则变为N - 1 #inc ...

  4. Codeforces 1110 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...

  5. codeforces 891E Lust 题解

    题目传送门 题目大意: 给出一个长度为 nnn 的序列,进行 kkk 次操作,每次随机选取一个 aia_iai​,让答案加上 aaa 序列中的其他数的乘积,然后让 ai−1a_i-1ai​−1,问最后 ...

  6. codeforces round #827题解(完整)

    Problem - A - Codeforces 大致意思就是说给定三个数,判断是否存在一个数是另外两个数之和. #include<bits/stdc++.h> using namespa ...

  7. Codeforces 967 C 题解报告

    一.题目 http://codeforces.com/contest/967/problem/C 二.思路 (一)如果是同一楼层,则直接走过去,不用爬楼梯也不用乘电梯. (二)如果是不同楼层,分别计算 ...

  8. Codeforces ECR50 div2题解

    A:签到 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  9. Codeforces Round #621题解

    A. CowandHaybalesCow\ and\ HaybalesCow and Haybales 贪心模拟题. #include<iostream> #include<ioma ...

最新文章

  1. windows 域的一些概念
  2. 百度地图报错:APP Referer校验失败
  3. 教你如何玩转redis-简单消息队列
  4. Centos/RedHat 7/6/5切换阿里云源并安装EPEL/IUS/REMI仓库
  5. 用 Python 实现文件查找
  6. 不说技术~我需要调整自己,最近整整两天状态不是很好
  7. [深度学习]实现一个博弈型的AI,从五子棋开始(1)
  8. Caused by: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
  9. Laravel——Passport OAuth
  10. linux cp -d复制软链接文件
  11. OnInit 和 Page_Init 事件有什么不同
  12. C# 枚举类型在switch case语句中的使用
  13. 设置背景图片模糊,内容不模糊
  14. DirectUI的初步分析-转
  15. 联控智能无刷电机板子运行STM32 FOC 5.x电机库的程序,电机转一会儿会自动停下来的解决办法
  16. web开发网,前端实战项目百度云
  17. 2022-2027年中国石油装备制造市场竞争态势及行业投资前景预测报告
  18. 婚宴座位图html5,婚宴座位安排图 婚宴主桌安排示意图
  19. CSAPP第七章家庭作业参考答案
  20. ssdt函数索引号_shadow ssdt 服务表函数索引

热门文章

  1. 你的年货买齐了吗?2023最全年货清单列表
  2. 字符串分割函数--strtok与strsep
  3. Python爬取网站图片数据
  4. 自适应滤波器:最小均方误差(LMS)滤波器
  5. rabbitmq将默认root用户切换为其他用户
  6. java 自动微分,MIT开源高性能自动微分框架Enzyme:速度提升4.5倍
  7. 通过 Windows 用户模式回调实施的内核攻击
  8. 途牛旅游项目——搜索与分页的后台代码
  9. 动手学数据分析 TASK2 数据清洗及特征处理
  10. 黑鲨android的开机密码,黑鲨研习win10系统删除开机密码的处理步骤