热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Codeforces494BObsessiveString题解(KMP+DP)

题目:CF494B.题目大意:给定两个字符串SSS和TTT,在SSS中抽取几个不相交的子串,使得TTT均是这些子串的子串&#

题目:CF 494 B.
题目大意:给定两个字符串SSSTTT,在SSS中抽取几个不相交的子串,使得TTT均是这些子串的子串,问有多少种方案.
1≤∣S∣,∣T∣≤1051\leq |S|,|T|\leq 10^51S,T105.

仔细一看感觉题目好像比较难,但看完题解后感觉这也是一道比较容易的套路题,KMP与DP结合的题做的少啊…

首先很容易想到第一个串的子串必须包含第二个串,就很自然想到用KMP将第二个串在第一个串中出现的位置都找出来,那么所有的子串都必须包含这些位置.

考虑计算出一个数组val[i]val[i]val[i]表示第iii个字符前最近的匹配点(第iii个点不一定要匹配),发现这个数组可以很容易用KMP求出匹配点后稍微处理一下求出.

考虑应用valvalval数组,设f[i]f[i]f[i]表示到前iii个字符的方案数(所选子串中不一定要包含第iii个字符),然后很容易发现这个状态的转移有两种情况:
1.去掉第iii个字符,也就是f[i−1]f[i-1]f[i1].
2.找到最近的匹配点val[i]val[i]val[i],考虑f[1..val[i]−1]f[1..val[i]-1]f[1..val[i]1],发现可以只选串[val[i]..i][val[i]..i][val[i]..i]或者在f[1..val[i]−1]f[1..val[i]-1]f[1..val[i]1]后面直接加入这个串.

所以转移就是:
f[i]=f[i−1]+val[i]+∑j=1val[i]−1f[j]f[i]=f[i-1]+val[i]+\sum_{j=1}^{val[i]-1}f[j] f[i]=f[i1]+val[i]+j=1val[i]1f[j]

转移出来之后,发现答案就是f[n]f[n]f[n]了,所以直接输出就好.

代码如下:

#includeusing namespace std;#define Abigail inline void
typedef long long LL;const int N=100000;
const LL mod=1000000007;char s[N+9],t[N+9];
int n,m,nxt[N+9];
LL f[N&#43;9],sum[N&#43;9],val[N&#43;9];void add(LL &a,LL b){a&#43;&#61;b;while (a>&#61;mod) a-&#61;mod;}void self_mate(){int j&#61;0;nxt[1]&#61;0;for (int i&#61;2;i<&#61;m;&#43;&#43;i){while (t[i]^t[j&#43;1]&&j>0) j&#61;nxt[j];if (t[i]&#61;&#61;t[j&#43;1]) &#43;&#43;j;nxt[i]&#61;j;}
}void mate(){int j&#61;0;for (int i&#61;1;i<&#61;n;&#43;&#43;i){while (s[i]^t[j&#43;1]&&j>0) j&#61;nxt[j];if (s[i]&#61;&#61;t[j&#43;1]) &#43;&#43;j;if (j&#61;&#61;m){val[i]&#61;i-m&#43;1;j&#61;nxt[j];}}
}void solve(){for (int i&#61;1;i<&#61;n;&#43;&#43;i)if (val[i]&#61;&#61;0) val[i]&#61;val[i-1];for (int i&#61;1;i<&#61;n;&#43;&#43;i){f[i]&#61;f[i-1];if (val[i]) add(f[i],sum[val[i]-1]&#43;val[i]);add(sum[i],sum[i-1]&#43;f[i]);}
}Abigail into(){scanf("%s",s&#43;1);scanf("%s",t&#43;1);n&#61;strlen(s&#43;1);m&#61;strlen(t&#43;1);
}Abigail work(){self_mate();mate();solve();
}Abigail outo(){printf("%I64d\n",f[n]);
}int main(){into();work();outo();return 0;
}


推荐阅读
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
author-avatar
liuleyi
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有