KMP-CF535D-Tavas and Malekas

题意:

给 定 模 式 串 s t r , 以 及 m 个 位 置 p o s [ i ] , 1 < = i < = m , 要 求 从 位 置 p o s [ i ] 开 始 的 后 缀 子 串 的 前 缀 要 包 含 s t r , 求 满 足 条 件 的 , 长 度 为 n 的 字 符 串 共 有 多 少 种 可 能 。 给定模式串str,以及m个位置pos[i],1<=i<=m,要求从位置pos[i]开始的后缀子串的前缀要包含str,\\求满足条件的,长度为n的字符串共有多少种可能。 给定模式串str,以及m个位置pos[i],1<=i<=m,要求从位置pos[i]开始的后缀子串的前缀要包含str,求满足条件的,长度为n的字符串共有多少种可能。

输入输出:

Input:
The first line contains two integers n and m, the length of s and the length of the subsequence Malekas wrote down (1 ≤ n ≤ 106 and 0 ≤ m ≤ n - |p| + 1).

The second line contains string p (1 ≤ |p| ≤ n).

The next line contains m space separated integers y1, y2, …, ym, Malekas’ subsequence (1 ≤ y1 < y2 < … < ym ≤ n - |p| + 1).

Output:
In a single line print the answer modulo 1000 000 007.

Sample Input:
6 2
ioi
1 3

Sample Output:
26

Sample Input:
5 2
ioi
1 2

Sample Output:
0

Note:
In the first sample test all strings of form “ioioi?” where the question mark replaces arbitrary English letter satisfy.

Here |x| denotes the length of string x.

Please note that it’s possible that there is no such string (answer is 0).

EG:

样 例 1 : 给 定 母 串 长 度 n = 6 , 模 式 串 长 度 m = 3 , 模 式 串 为 i o i , 要 求 从 1 , 3 位 置 开 始 的 后 缀 子 串 的 前 缀 为 i o i , 可 以 确 定 长 度 为 6 的 母 串 的 前 5 位 字 符 为 i o i o i _ , 第 六 位 可 填 任 意 字 母 , 因 此 满 足 题 意 的 数 量 为 2 6 1 = 26 。 样例1:给定母串长度n=6,模式串长度m=3,模式串为ioi,要求从1,3位置开始的后缀子串的前缀为ioi,\\可以确定长度为6的母串的前5位字符为ioioi\_,第六位可填任意字母,因此满足题意的数量为26^1=26。 样例1:给定母串长度n=6,模式串长度m=3,模式串为ioi,要求从1,3位置开始的后缀子串的前缀为ioi,可以确定长度为6的母串的前5位字符为ioioi_,第六位可填任意字母,因此满足题意的数量为261=26。

题解:

一 开 始 的 想 法 是 先 计 算 相 邻 位 置 p o s [ i + 1 ] 与 p o s [ i ] 之 差 , 若 差 小 于 模 式 串 长 度 l e n − 1 就 无 法 满 足 条 件 , 若 恰 好 等 于 l e n − 1 , 还 需 要 判 断 模 式 串 的 第 一 个 字 符 和 最 后 一 个 字 符 是 否 相 同 , 如 样 例 2 。 一开始的想法是先计算相邻位置pos[i+1]与pos[i]之差,若差小于模式串长度len-1就无法满足条件,\\若恰好等于len-1,还需要判断模式串的第一个字符和最后一个字符是否相同,如样例2。 一开始的想法是先计算相邻位置pos[i+1]与pos[i]之差,若差小于模式串长度len−1就无法满足条件,若恰好等于len−1,还需要判断模式串的第一个字符和最后一个字符是否相同,如样例2。

现 在 发 现 了 思 考 的 漏 洞 : 现在发现了思考的漏洞: 现在发现了思考的漏洞:

如 : 模 式 串 a b a b , 长 度 l e n = 4 , 若 两 个 相 邻 位 置 间 隔 为 1 , 1 < 4 − 1 = 3 , 却 仍 然 可 以 满 足 题 意 。 如:模式串abab,长度len=4,若两个相邻位置间隔为1,1<4-1=3,却仍然可以满足题意。 如:模式串abab,长度len=4,若两个相邻位置间隔为1,1<4−1=3,却仍然可以满足题意。

所以,判断的依据应当是模式串最长相同前后缀的长度!

接 下 来 需 要 统 计 相 邻 位 置 之 间 “ 可 以 填 任 意 字 母 ” 的 位 置 的 个 数 , 也 不 要 忘 了 最 后 要 判 断 总 长 度 是 否 超 过 n 。 求 出 总 的 “ 空 位 ” 个 数 c n t , 再 计 算 2 6 c n t 即 最 终 方 案 总 数 。 接下来需要统计相邻位置之间“可以填任意字母”的位置的个数,也不要忘了最后要判断总长度是否超过n。\\求出总的“空位”个数cnt,再计算26^{cnt}即最终方案总数。 接下来需要统计相邻位置之间“可以填任意字母”的位置的个数,也不要忘了最后要判断总长度是否超过n。求出总的“空位”个数cnt,再计算26cnt即最终方案总数。

用 到 最 长 相 同 前 后 缀 的 长 度 , 想 到 K M P 算 法 中 的 N e x t 数 组 。 用到最长相同前后缀的长度,想到KMP算法中的Next数组。 用到最长相同前后缀的长度,想到KMP算法中的Next数组。

N e x t [ i ] : 前 i 个 字 符 中 , 前 缀 与 后 缀 相 同 部 分 最 长 的 长 度 。 Next[i]:前i个字符中,前缀与后缀相同部分最长的长度。 Next[i]:前i个字符中,前缀与后缀相同部分最长的长度。

所 以 我 们 对 模 式 串 求 N e x t 数 组 后 , 利 用 N e x t 数 组 从 模 式 串 末 尾 开 始 , 递 归 标 记 每 一 个 循 环 节 的 前 一 个 循 环 节 的 一 端 。 所以我们对模式串求Next数组后,利用Next数组从模式串末尾开始,递归标记每一个循环节的前一个循环节的一端。 所以我们对模式串求Next数组后,利用Next数组从模式串末尾开始,递归标记每一个循环节的前一个循环节的一端。

如 : 对 模 式 串 a b a b , i : 1 2 3 4 N e x t [ i ] : 0 0 1 2 , 我 们 把 从 末 尾 4 开 始 标 记 , 接 着 N e x t [ 4 ] = 2 , 再 把 2 标 记 。 若 模 式 串 长 度 减 去 相 邻 位 置 的 间 隔 恰 好 被 标 记 过 , 即 l e n − ( p o s [ i + 1 ] − p o s [ i ] ) 在 模 式 串 中 的 位 置 恰 好 是 前 一 个 循 环 节 的 一 端 , 说 明 可 行 。 反 应 到 上 图 就 是 4 − 2 = 2 , 恰 好 是 后 一 个 循 环 节 a b 的 前 一 个 循 环 节 a b 的 后 端 所 在 的 位 置 。 如:对模式串abab,\\ \qquad \quad i: 1\ \ 2\ \ 3\ \ 4\\Next[i]: \ 0\ \ 0\ \ 1\ \ 2,\\我们把从末尾4开始标记,接着Next[4]=2,再把2标记。\\若模式串长度减去相邻位置的间隔恰好被标记过,\\即len-(pos[i+1]-pos[i])在模式串中的位置恰好是前一个循环节的一端,说明可行。\\反应到上图就是4-2=2,恰好是后一个循环节ab的前一个循环节ab的后端所在的位置。 如:对模式串abab,i:1  2  3  4Next[i]: 0  0  1  2,我们把从末尾4开始标记,接着Next[4]=2,再把2标记。若模式串长度减去相邻位置的间隔恰好被标记过,即len−(pos[i+1]−pos[i])在模式串中的位置恰好是前一个循环节的一端,说明可行。反应到上图就是4−2=2,恰好是后一个循环节ab的前一个循环节ab的后端所在的位置。

具体落实:

① 、 利 用 K M P 中 的 N e x t 数 组 来 判 断 , 从 最 后 一 个 循 环 节 向 前 标 记 每 一 个 循 环 节 的 末 端 。 ①、利用KMP中的Next数组来判断,从最后一个循环节向前标记每一个循环节的末端。 ①、利用KMP中的Next数组来判断,从最后一个循环节向前标记每一个循环节的末端。
② 、 计 算 相 邻 位 置 的 间 隔 , 若 间 隔 长 度 小 于 模 式 串 的 长 度 − 1 , 则 需 要 判 断 是 否 处 在 某 循 环 节 的 末 端 位 置 。 ③ 、 计 算 所 有 “ 空 位 ” 的 数 量 c n t , 总 的 方 案 数 即 2 6 c n t 。 ②、计算相邻位置的间隔,若间隔长度小于模式串的长度-1,则需要判断是否处在某循环节的末端位置。\\③、计算所有“空位”的数量cnt,总的方案数即26^{cnt}。 ②、计算相邻位置的间隔,若间隔长度小于模式串的长度−1,则需要判断是否处在某循环节的末端位置。③、计算所有“空位”的数量cnt,总的方案数即26cnt。

注意:
① 、 m = 0 的 情 况 不 能 漏 了 特 判 。 ② 、 最 后 一 个 位 置 的 模 式 串 可 能 会 超 过 长 度 n 。 ③ 、 第 一 个 位 置 未 必 是 1 , 因 此 第 一 个 位 置 之 前 仍 然 可 能 存 在 “ 空 位 ” 。 ①、m=0的情况不能漏了特判。\\②、最后一个位置的模式串可能会超过长度n。\\③、第一个位置未必是1,因此第一个位置之前仍然可能存在“空位”。 ①、m=0的情况不能漏了特判。②、最后一个位置的模式串可能会超过长度n。③、第一个位置未必是1,因此第一个位置之前仍然可能存在“空位”。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#define ll  long long
#define inf 0x7fffffff
using namespace std;
const int mod=1e9+7;
const int N=1e6+10;
int n,m,len;   ///len为模式串的长度
char s[N];
int pos[N],Next[N];
bool mark[N];   ///标记void get_next()
{for(int i=2,j=0;i<=len;i++){while(j&&s[i]!=s[j+1]) j=Next[j];if(s[i]==s[j+1]) j++;Next[i]=j;}
}ll quick_pow(ll a,ll b)
{ll ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans%mod;
}int main()
{cin>>n>>m;scanf("%s",s+1);if(!m) {printf("%lld\n",quick_pow(26,n));return 0;}   ///不能忘了特判m=0len=strlen(s+1);get_next();for(int i=len;i;i=Next[i]) mark[i]=true;for(int i=1;i<=m;i++){scanf("%d",&pos[i]);if(i!=1&&pos[i]-pos[i-1]<len)   ///相邻位置间隔小于模式串长度的情况,需要判断是否被Next数组标记过{if(!mark[ pos[i-1]+len-pos[i] ]){cout<<0<<endl;return 0;}}}if(n-pos[m]<len-1) cout<<0<<endl;  ///判断最后一个位置是否会超过长度nelse  ///统计空位的数量{int cnt=pos[1]-1;  ///第一个位置前的数字也是任意的for(int i=2;i<=m;i++)if(pos[i]-pos[i-1]>len)cnt+=pos[i]-pos[i-1]-len;cnt+=n-pos[m]-len+1;  ///加上最后一个位置到末尾的空位printf("%lld\n",quick_pow(26,cnt));}return 0;
}

KMP-CF535D-Tavas and Malekas相关推荐

  1. Codeforces Round #299 (Div. 2) D. Tavas and Malekas kmp

    题目链接: http://codeforces.com/problemset/problem/535/D D. Tavas and Malekas time limit per test2 secon ...

  2. 浅析字符串匹配算法——KMP算法(附CF 535D-Tavas and Malekas)

    引入 在计算机中,人类的语言.文字等往往利用字符串进行保存,而字符串的匹配也对人们的生活产生着举足轻重的作用,例如个人信息的匹配.搜索引擎的使用等,为了在庞大的数据中找到我们所需的数据,字符串匹配的效 ...

  3. kmp求前缀和后缀的最大重复部分

    hdu 2594 kmp水题 求s1的前缀和s2的后缀重复度的最大值 2013-06-05 11:16 1199人阅读 评论(0) 收藏 举报  分类: KMP(8)  版权声明:本文为博主原创文章, ...

  4. BF算法优化-------KMP算法

    百度百科:KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的核心是利用 ...

  5. MUV LUV EXTRA 2019CCPC秦皇岛站J题 KMP

    题目链接 题意:意思给你俩数一个字符串,然后让你对字符串小数点后边的字符串进行处理,找个一个循环节以及对应出现的长度, 然后用a*p-b*l算得到一个最大值 那肯定循环节就想到了KMP了,然后循环长度 ...

  6. 数据结构与算法(5)字符串(BF算法、KMP算法及KMP算法优化)

    目录 一.BF算法(暴力算法) 二.KMP算法 三.KMP算法优化 一.BF算法(暴力算法) 一个一个往后匹配,匹配失败继续从母串下一个和头(子串的头)往后继续匹配. 虽然简单,但是需要较多的时间复杂 ...

  7. 字符串匹配算法 -- BM(Boyer-Moore) 和 KMP(Knuth-Morris-Pratt)详细设计及实现

    文章目录 1. 算法背景 2. BM(Boyer-Moore)算法 2.1 坏字符规则(bad character rule) 2.2 好后缀规则(good suffix shift) 2.3 复杂度 ...

  8. 【笔记】震惊!世上最接地气的字符串浅谈(HASH+KMP)

    震惊!世上最接地气的字符串浅谈(HASH+KMP) 笔者过于垃圾,肯定会有些错的地方,欢迎各位巨佬指正,感激不尽! 引用:LYD的蓝书,一本通,DFC的讲稿,网上各路巨佬 Luguo id: 章鱼那个 ...

  9. hiho 1015 KMP算法 CF 625 B. War of the Corporations

    #1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

最新文章

  1. MySQL 4种text类型的最大长度
  2. 排序算法——堆排序(C++)
  3. Java中proc是什么意思,在java里头读取/proc/net/dev
  4. python中if语句的实例_对python中if语句的真假判断实例详解
  5. 数学是成就卓越开发人员的必备技能
  6. hdu4848 求到达每一个点总时间最短(sum[d[i]])。
  7. UI设计3-切图、网页设计规范
  8. CV520国产兼容应用及说明
  9. “颠覆”——物联网 + 大数据 + 云计算+ 网络互连
  10. python计算球体表面积和体积_图解球体表面积和体积正确计算方法及计算公式(原创)...
  11. Pycharm提示“typo:in word“的意思
  12. WordPress整合ckplayer X3视频播放器插件
  13. 在access中记录的末尾标志是什么_access习题--报表和页
  14. 博达网站服务器地址怎么查,路由器博达路由器配置经典教程
  15. Brave 安全隐私浏览器
  16. EAUML日拱一卒-微信小程序实战:位置闹铃 (15)-实现监控点状态迁移功能
  17. 2-linux详细安装Redis及shutdown命令失效解决
  18. 艺术市场的区块链革命
  19. 乐理基础知识-5.和弦
  20. Github拉代码太慢怎么办?

热门文章

  1. gamma函数、beta分布、贝叶斯平滑、特征校准
  2. 几大分布:正态分布、卡方分布、t分布、F分布整理
  3. php保留数字小数点后两位方法
  4. 漫画爬虫的一个小小的例子
  5. 用Tableau制作导出图像按钮
  6. 增加Cache命中率加快程序运行速度
  7. 冒泡排序的代码java_冒泡排序java代码实现
  8. %matplotlib和%pylab的绘图的方式及使用
  9. 用python画小动物大全_python3用turtle库进行绘制小猪佩奇图案
  10. Oracle Flashback(闪回) 详解