题意简述

有一个空着的长度为\(n\)的字符串\(ans\),再给出一个长度为\(m\)的序列\(a\),现要在序列中每个元素\(a_i\)的位置开始都规定必须为一个给定的字符串\(s\)。问字符串\(ans\)的可能种类。

解法

主要考虑有可能\(a_i\)之间互相冲突导致直接输出\(0\),于是我们需要快速判断当前字符串\(s\)的首与尾是否匹配。显然有两种可行解法,第一种是KMP,第二种是玄学的字符串哈希。但是写这篇题解的蒟蒻不想打KMP,于是就写了一个哈希。

这里的哈希其实只用单哈希即可,模数我一开始取成\(99844353\),目测不是个质数,但是竟然过了QAQ,然后换成\(998244353\)(丝毫不怕被卡的样子),结果果断被卡(WA on test 31),于是果断使用了\(19260817\),就A掉了。

再讲一下字符串哈希结束之后的判断答案的种类数的做法,我们直接统计满足\(a_{i+1}-a_{i}>len\)的\(a_{i+1}-a_{i}-len\)的个数之和即可,注意首尾的特殊处理。

然后我们设刚才统计的个数为\(cnt\)个,那么答案就是\(26^{cnt}\),连快速幂都不用打,直接暴力乘即可,最后注意取模

代码

\(ch\)数组是上文中的字符串\(s\)

\(p\)是本题规定的模数

\(MOD\)是哈希的模数,\(BASE\)是哈希的基数

\(getVal\)函数用于取出\([l,r]\)的哈希值

#include <cstdio>
#include <cstring>
#define p 1000000007 int read(){
int x = 0; int zf = 1; char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;
} char ch[1000005];
long long res[1000005];
long long fac[1000005];
const long long MOD = 9982442353ll;
const long long prime = 431ll;
const long long BASE = 131ll; void getHash(int n){
res[0] = 1; fac[0] = 1;
for (int i = 1; i <= n; ++i)
fac[i] = (fac[i - 1] * BASE) % MOD;
for (int i = 1; i <= n; ++i)
res[i] = (res[i - 1] * BASE + (ch[i] - 'A') * prime) % MOD;
} inline long long getVal(int l, int r){
return ((res[r] - ((res[l - 1] * fac[r - l + 1]) % MOD) + MOD) % MOD);
} int a[1000005]; int main(){
int n = read(), m = read();
scanf("%s", ch + 1);
int len = strlen(ch + 1);
if (!m){
long long ans = 1;
for (int i = 1; i <= n; ++i)
(ans *= 26) %= p;
printf("%lld", ans);
return 0;
}
getHash(len);
for (int i = 1; i <= m; ++i){
a[i] = read();
if (a[i] + len - 1 > n){
puts("0");
return 0;
}
if (i > 1 && a[i - 1] + len > a[i]){
int x = a[i - 1] + len - a[i];
if (getVal(len - x + 1, len) != getVal(1, x)){
puts("0");
return 0;
}
}
}
int cnt = a[1] - 1;
for(int i = 1; i < m; i++){
if(a[i] + len < a[i + 1]){
cnt += a[i + 1] - a[i] - len;
}
}
cnt += n - a[m] - len + 1;
long long ans = 1;
for (int i = 1; i <= cnt; ++i)
(ans *= 26) %= p;
printf("%lld", ans);
return 0;
}

[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. D. Tavas and Malekas 解析(字串匹配)

    Codeforce 535 D. Tavas and Malekas 解析(字串匹配) 今天我們來看看CF535D 題目連結 題目 給你一個字串$p$和一些$index$代表字串$p$在哪些位置會和長 ...

  3. Codeforces 535D - Tavas and Malekas

    535D - Tavas and Malekas 题目大意:给你一个模板串,给你一个 s 串的长度,告诉你 s 串中有 m 个模板串并告诉你,他们的其实位置, 问你这样的 s 串总数的多少,答案对1e ...

  4. Tavas and Malekas

    题面 题目描述 给你两个字符串a和b,告诉所有你b在a中一定匹配的位置,求有中不同的字符串a.a的长度为n,b的长度为m,一定匹配的位置有p个.若b在a中的一定匹配的位置为x,说明a[x-x+m-1] ...

  5. 【Codeforces Round #299 (Div. 2) D】Tavas and Malekas

    [链接] 我是链接,点我呀:) [题意] 给你n个位置,然后让你从某些位置开始的|p|个位置,填上p这个字符串. 问你填的时候是否会发生冲突->输出0 否则输出最终n个位置组成的可能的字符串的总 ...

  6. codeforces 535D. Tavas and Malekas KMP

    题目链接 又复习了一遍kmp....之前都忘光了 #include<bits/stdc++.h> using namespace std; #define pb(x) push_back( ...

  7. CF #299 div1 B. Tavas and Malekas KMP-next数组

    题目链接:http://codeforces.com/contest/536/problem/B 一个原始字符串,一个未知字符串,每一次从pos[i]开始覆盖未知字符串,问最后字符串的形式,以及判断过 ...

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

    KMP,先预处理按每个节点标记,扫一遍更新每个匹配位置,最后kmp判断是否有重合而且不相同的地方 注意处理细节,很容易runtime error #include<map> #includ ...

  9. D. Tavas and Malekas DFS模拟 + kmp + hash || kmp + hash

    http://codeforces.com/contest/535/problem/D 如果真的要把m个串覆盖上一个串上面,是可以得,不会超时. 要注意到一点,全部覆盖后再判断时候合法,和边放边判断, ...

随机推荐

  1. 20191128 Spring Boot官方文档学习(9.4-9.8)

    9.4.Spring MVC Spring Boot有许多启动器包含Spring MVC.请注意,一些启动器包括对Spring MVC的依赖,而不是直接包含它. 9.4.1.编写JSON REST服务 ...

  2. RHEL 无图形界面安装oracle 11gr2

    RHEL7.3  无图形界面安装oracle 11gr2  使用纯命令安装方式.提供RHEL全量系统镜像.   1.oracle官方下载地址:https://www.oracle.com/techne ...

  3. MySQL-快速入门(2)数据类型

    1.MySQL支持多种数据类型: 1>数值类型:整数类型tinyint.smallint.mediumint.bigint.int:浮点小数类型float.double:定点小数类型decima ...

  4. CentOS 7安装Python 2.6(与已有版本共存)

    1. 安装需要用到的包 yum install -y zlib-devel bzip2-devel openssl-devel xz-libs wget 2. 下载 Python 2.6.8 版本 w ...

  5. 极*Java速成教程 - (7)

    Java高级特性 数组 在Java中,数组是一串连续的,不可改变长度的,对象被固定的,类型固定的连续空间.数组中的随机访问非常迅速,但为了速度放弃了灵活性.而效率也是数组最大的优点. 在使用泛型的容器 ...

  6. IntelliJ IDEA 2019.3 这回真的要飞起来了,新特性抢先看!

    IntelliJ IDEA 才公布下一个主要版本 2019.3 的 Roadmap,近日就发布了 IntelliJ IDEA 2019.3 的首个早期访问版本(即 EAP 版本),版本号为 2019. ...

  7. 循环结构 :for

    循环结构 :for 循环四要素: 1.初始化条件 2.循环条件 3.循环体 4.迭代条件 格式: for(初始化条件;循环条件;迭代条件){ 循环体; } 执行顺序 :1 -> 2 -> ...

  8. CQOJ921B素数和

    这是用一道搜索(全排列)实现的一个数论题目.今天周六,上了一天信息,没写数学的我瑟瑟发抖. 首先题意为给定n个数,选取k个数进行求和,输出和为素数的方案数.在写判断素数函数时,我们只需要把i枚举到根下 ...

  9. anconda下安装opencv

    提示:如果你安装了python其它版本,或者在anaconda中创建了虚拟环境,应该先激活你的环境,然后再在命令窗口执行下面的操作 1.首先下载所需镜像文件: 我们需要上网站去下载我们需要的版本. 官 ...

  10. STL: HDU1004Let the Balloon Rise

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...