Codeforces 536B Tavas and Malekas 求自身首尾的重叠位置 KMP

题目链接:点击打开链接

题意:

用小写字母构造n长的串S,m个要求

字符串P

下面m个位置。a1, a2···am(输入有序)

要使得字符串S的以ai 开头且后面是一个P串。

问构造的方法数

思路:

实际上,对于ai, ai+1 ,两个位置,如果这两个位置会相互影响(即 ai+1 - ai < len)

复制一个和P一样的串P‘

把P放在ai位置,把P‘放在ai+1位置,那么只需要判断一下 P的后半段是否和P‘的前半段匹配即可。

也就是P’的哪些位置是和P的尾部相同的。

KMP求出这些位置放到set里。

然后就是简单的判断了

#include <stdio.h>
#include <string.h>
#include <string>
#include <math.h>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
#include <iostream>
using namespace std;
template <class T>
inline bool rd(T &ret) {
	char c; int sgn;
	if (c = getchar(), c == EOF) return 0;
	while (c != '-' && (c<'0' || c>'9')) c = getchar();
	sgn = (c == '-') ? -1 : 1;
	ret = (c == '-') ? 0 : (c - '0');
	while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
	ret *= sgn;
	return 1;
}
template <class T>
inline void pt(T x) {
	if (x <0) {
		putchar('-');
		x = -x;
	}
	if (x>9) pt(x / 10);
	putchar(x % 10 + '0');
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;

int f2[N], len;
char s1[N], s2[N];
void getFail(int *f, char *P){
	f[0] = f[1] = 0;
	for (int i = 1; i < len; i++){
		int j = f[i];
		while (j&&P[i] != P[j])j = f[j];
		f[i + 1] = P[i] == P[j] ? j + 1 : 0;
	}
}

set<int>s;
void KMP(int *f, char *S1, char *S2){
	getFail(f, S2);
	int j = 0, i = 0;
	while (i <= len)
	{
		while (j && S1[i] != S2[j]) j = f[j];
		i++, j++;
	}
	for (int i = len; f[i]; i = f[i])
		s.insert(len-f[i]);
}
int m, n;
bool v[N];
int main() {
	while (cin >> n){
		rd(m);
		scanf("%s", s1);
		while (m--){
			int u; rd(u);
			v[u] = true;
		}
		len = strlen(s1);
		memcpy(s2, s1, sizeof s1);
		KMP(f2, s1, s2);

		ll ans = 1;
		for (int i = 1, last = -1e7; i <= n; i++){
			if (v[i] == false && i - last >= len){
				ans *= 26LL;
				if (ans >= mod)ans %= mod;
			}
			else if (v[i] == true){
				if (i - last < len && !s.count(i-last)){
					ans = 0; break;
				}
				last = i;
			}
		}
		pt(ans%mod); puts("");
	}
	return 0;
}
时间: 2024-10-05 05:05:00

Codeforces 536B Tavas and Malekas 求自身首尾的重叠位置 KMP的相关文章

Codeforces 535D - Tavas and Malekas

535D - Tavas and Malekas 题目大意:给你一个模板串,给你一个 s 串的长度,告诉你 s 串中有 m 个模板串并告诉你,他们的其实位置, 问你这样的 s 串总数的多少,答案对1e9+7取模. 我感觉我英语是不是不行啊,我以为他的意思是他里面一共只有m个匹配串,想着没有其他的匹配串,感觉 好麻烦好麻烦好麻烦啊!!!!!! 思路:最暴力的思路,他给你一个匹配串的位置,你就在s串上更新,如果遇到没有已经被更新而且字符不同时 输出0,然后统计剩下的未知字符的个数x,答案就是 (26

codeforces 535D. Tavas and Malekas KMP

题目链接 又复习了一遍kmp....之前都忘光了 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson

【Codeforces 536B】Tavas and Malekas

536B Tavas and Malekas 题意:给一个字符串,现在要把这个字符串在一个大空字符串中放多次,每一次的开头在\(p_i\)位置,然后现在问这个大字符串有多少种情况. 思路:首先如果两个字符串放置的位置有重叠,重叠部分必须相等. 那么就是一个前缀要等于一个后缀. 所以果断z function.这样的话写起来比kmp快... 然后就可以对于每两个连续出现判断这些重复部分的交叉状况,同时算上所有的非自由的字符,最后求出\(2^{自由字符数量}\)即可. 原文地址:https://www

CodeForces 61E Enemy is weak 求i&lt;j&lt;k &amp;&amp; a[i]&gt;a[j]&gt;a[k] 的对数 树状数组

题目链接:点击打开链接 题意是求 i<j<k && a[i]>a[j]>a[k] 的对数 如果只有2元组那就是求逆序数的做法 三元组的话就用一个树状数组x表示 数字i前面有多少个比自己大的个数 然后每次给这个y数组求和,再把x中>a[i]的个数存入y中即可 #include <algorithm> #include <cctype> #include <cassert> #include <cstdio> #in

Maximal Area Quadrilateral CodeForces - 340B || 三点坐标求三角形面积

Maximal Area Quadrilateral CodeForces - 340B 三点坐标求三角形面积(可以带正负,表示向量/点的不同相对位置): http://www.cnblogs.com/xiexinxinlove/p/3708147.html https://jingyan.baidu.com/article/a65957f49596ab24e67f9be7.html 枚举对角线,求出在对角线两侧取任意点能得到的三角形的面积,然后对于每条对角线,最大值就是两侧面积最大值之和. 1

HDU 3518 Boring counting(后缀数组啊 求字符串中不重叠的重复出现至少两次的子串的个数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3518 Problem Description 035 now faced a tough problem,his english teacher gives him a string,which consists with n lower case letter,he must figure out how many substrings appear at least twice,moreover

POJ 1743 后缀数组:求最长不重叠子串

数据:这题弄了好久,WA了数十发,现在还有个例子没过,可却A了,POJ 的数组也太弱了. 10 1 1 1 1 1 1 1 1 1 1 这组数据如果没有那个n-1<10判断的话,输入的竟然是5,我靠-- 思路:这个题目关键的地方有两个:第一,重复的子串一定可以看作是某两个后缀的公共前缀,第二,把题目转化成去判定对于任意的一个长度k,是否存在长度至少为k的不重叠的重复的子串. 转化成判定问题之后,就可以二分去解答了.在验证判定是否正确时,我们可以把相邻的所有不小于k的height[]看成一组,然后

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

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

codeforces535D:Tavas and Malekas(KMP)

Tavas is a strange creature. Usually "zzz" comes out of people's mouth while sleeping, but string s of length n comes out from Tavas' mouth instead. Today Tavas fell asleep in Malekas' place. While he was sleeping, Malekas did a little process o