KMP,ACM集训

2023-09-21 20:11:14

目录

                                831. KMP字符串

输入格式

输出格式

数据范围

输入样例:

输出样例:

 解析:KMP模板

                        D - Cyclic Nacklace

解析:KMP-next数组应用+循环字符串判断

                                F - Power Strings

解析:KMP-next数组应用+循环字符串判断

                                H - Count the string

 解析:next数组理解

                                J - String Problem

 解析:kmp求循环节,最小/最大表示法


                                831. KMP字符串

831. KMP字符串 - AcWing题库

给定一个字符串 S,以及一个模式串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。

模式串 P 在字符串 S 中多次作为子串出现。

求出模式串 P 在字符串 S 中所有出现的位置的起始下标。

输入格式

第一行输入整数 N,表示字符串 P 的长度。

第二行输入字符串 P。

第三行输入整数 M,表示字符串 S 的长度。

第四行输入字符串 S。

输出格式

共一行,输出所有出现位置的起始下标(下标从 00 开始计数),整数之间用空格隔开。

数据范围

1≤N≤105
1≤M≤106

输入样例:
3
aba
5
ababa
输出样例:
0 2

 解析:KMP模板

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int N = 1e5 + 5, M = 1e6 + 5;

int n, m;
string s, p;
int ne[N];

int main() {
	cin >> n >> p >> m >> s;
	p.insert(0," ");
	s.insert(0," ");
	for (int i = 2, j = 0; i <= n; i++) {
		while (j && p[i] != p[j + 1])j = ne[j];
		if (p[i] == p[j + 1])j++;
		ne[i] = j;
	}
	for (int i = 1, j = 0; i <= m; i++) {
		while (j && s[i] != p[j + 1])j = ne[j];
		if (s[i] == p[j + 1])j++;
		if (j == n) {
			printf("%d ", i - n);
			j = ne[j];
		}
	}
	return 0;
}

                        D - Cyclic Nacklace

https://vjudge.net/contest/582298#problem/D

CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, without any surprise, there are only 99.9 yuan left. he is too distressed and thinking about how to tide over the last days. Being inspired by the entrepreneurial spirit of "HDU CakeMan", he wants to sell some little things to make money. Of course, this is not an easy task.

As Christmas is around the corner, Boys are busy in choosing christmas presents to send to their girlfriends. It is believed that chain bracelet is a good choice. However, Things are not always so simple, as is known to everyone, girl's fond of the colorful decoration to make bracelet appears vivid and lively, meanwhile they want to display their mature side as college students. after CC understands the girls demands, he intends to sell the chain bracelet called CharmBracelet. The CharmBracelet is made up with colorful pearls to show girls' lively, and the most important thing is that it must be connected by a cyclic chain which means the color of pearls are cyclic connected from the left to right. And the cyclic count must be more than one. If you connect the leftmost pearl and the rightmost pearl of such chain, you can make a CharmBracelet. Just like the pictrue below, this CharmBracelet's cycle is 9 and its cyclic count is 2:


Now CC has brought in some ordinary bracelet chains, he wants to buy minimum number of pearls to make CharmBracelets so that he can save more money. but when remaking the bracelet, he can only add color pearls to the left end and right end of the chain, that is to say, adding to the middle is forbidden.
CC is satisfied with his ideas and ask you for help.

Input

The first line of the input is a single integer T ( 0 < T <= 100 ) which means the number of test cases.
Each test case contains only one line describe the original ordinary chain to be remade. Each character in the string stands for one pearl and there are 26 kinds of pearls being described by 'a' ~'z' characters. The length of the string Len: ( 3 <= Len <= 100000 ).

Output

For each case, you are required to output the minimum count of pearls added to make a CharmBracelet.

Sample

InputcopyOutputcopy
3
aaa
abca
abcde
0
2
5

解析:KMP-next数组应用+循环字符串判断

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int N = 1e5 + 100, M = 1e4 + 5;
char str[N];
int ne[N];

int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		//memset(str, 0, sizeof(str));//千万不要加这句,加了就会WA,我也不知道为什么
		scanf("%s", str + 1);
		int len = strlen(str + 1);
		int n = len;
		for (int i = 2, j = 0; i <= n; i++) {
			while (j && str[i] != str[j + 1])j = ne[j];
			if (str[i] == str[j + 1])j++;
			ne[i] = j;
		}
		int r = len-ne[len];
		if (ne[len] == 0) {
			printf("%d\n", len);
		}
		else {
			if (len % r == 0)
				printf("0\n");
			else
				printf("%d\n", r - len % r);
		}
	}
	return 0;
}

                                F - Power Strings

Nefu字符串 - Virtual Judge (vjudge.net)

Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).

Input

Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

Output

For each s you should print the largest n such that s = a^n for some string a.

Sample

InputcopyOutputcopy
abcd
aaaa
ababab
.
1
4
3

Hint

This problem has huge input, use scanf instead of cin to avoid time limit exceed.

Sponsor

解析:KMP-next数组应用+循环字符串判断

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int N = 1e7 + 5;
int ne[N];
char str[N];

int main() {
	while (scanf("%s",  str + 1) != EOF) {
		if (str[1] == '.')
			break;
		int n = strlen(str + 1);
		for (int i = 2, j = 0; i <= n; i++) {
			while (j && str[i] != str[j + 1])j = ne[j];
			if (str[i] == str[j + 1])j++;
			ne[i] = j;
		}
		int r = n - ne[n];
		if (n % r == 0)
			printf("%d\n", n / r);
		else {
			printf("1\n");
		}
	}
	return 0;
}

                                H - Count the string

 Nefu字符串 - Virtual Judge (vjudge.net)

It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of this string. For example:
s: "abab"
The prefixes are: "a", "ab", "aba", "abab"
For each prefix, we can count the times it matches in s. So we can see that prefix "a" matches twice, "ab" matches twice too, "aba" matches once, and "abab" matches once. Now you are asked to calculate the sum of the match times for all the prefixes. For "abab", it is 2 + 2 + 1 + 1 = 6.
The answer may be very large, so output the answer mod 10007.

Input

The first line is a single integer T, indicating the number of test cases.
For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.

Output

For each case, output only one number: the sum of the match times for all the prefixes of s mod 10007.

Sample

InputcopyOutputcopy
1
4
abab
6

 解析:next数组理解

KMP中next数组的含义:0 - i 中的最大前缀后缀匹配

预处理出next数组,可知每个next数组记录该串的最大前缀的长度(数值上等价于下标)。那么对于某一个长位n的子串s,除了 它本身和模板串匹配外,还有它的最大相同后缀。
那么, ans = 本身的一个 + 最大相同后缀
关于不重不漏,由于答案的第一部分的头部都是模板串的第一个字符,对不同长度一定不同,对第二部分,末尾字符不会相同,同样不会重复

 虽然next数组统计的时最大前后缀,但大的后缀有前缀,那么大后缀中的小后缀一定也有前缀

注意:这道题中相同的部分不应该重叠,如:aaa 的答案为5

所以当前后缀相交时,此部分不计入答案。

好好理解理解!!!!

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int N = 2e5 + 5, P = 131,mod= 10007;
int n;
char str[N];
int ne[N];

int main() {
	int T;
	scanf("%d", &T);
	while (T--) {

		scanf("%d%s",&n, str + 1);
		for (int i = 2, j = 0; i <= n; i++) {
			while (j && str[i] != str[j + 1])j = ne[j];
			if (str[i] == str[j+1])j++;
			ne[i] = j;
		}
		LL ans = 0;
		for (int i = 1; i <= n; i++) {
			if (ne[i] != 0)
				ans=(ans+1)%mod;
		}
		ans = (ans + n) % mod;
		printf("%lld\n", ans);
	}
	return 0;
}

                                J - String Problem

Nefu字符串 - Virtual Judge (vjudge.net)

Give you a string with length N, you can generate N strings by left shifts. For example let consider the string “SKYLONG”, we can generate seven strings:
String Rank
SKYLONG 1
KYLONGS 2
YLONGSK 3
LONGSKY 4
ONGSKYL 5
NGSKYLO 6
GSKYLON 7
and lexicographically first of them is GSKYLON, lexicographically last is YLONGSK, both of them appear only once.
  Your task is easy, calculate the lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), its times, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.

Input

  Each line contains one line the string S with length N (N <= 1000000) formed by lower case letters.

Output

Output four integers separated by one space, lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), the string’s times in the N generated strings, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.

Sample

InputcopyOutputcopy
abcder
aaaaaa
ababab
1 1 6 1
1 6 1 6
1 3 2 3

 解析:kmp求循环节,最小/最大表示法

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int N = 1e6 + 5;

string str;
int ne[N];
int minrepresentation(string s) {
	int len = s.length();
	s = " " + s + s;
	int i = 1, j = 2;
	while (j <= len) {
		int k = 0;
		while (k < len && s[i + k] == s[j + k])k++;
		if (s[i + k] > s[j + k])i += k + 1;
		else j += k + 1;
		if (i == j)j++;
		if (i > j)swap(i, j);
	}
	return i;
}
int maxrepresentation(string s) {
	int len = s.length();
	s = " " + s + s;

	int i = 1, j = 2;
	while (j <= len) {
		int k = 0;
		while (k < len && s[i + k] == s[j + k])k++;
		if (s[i + k] < s[j + k])i += k + 1;
		else j += k + 1;
		if (i == j)j++;
		if (i > j)swap(i, j);
	}
	return i;
}
int main() {
	while (cin >> str) {
		int mn = minrepresentation(str);
		int mx = maxrepresentation(str);
		str.insert(0, " ");
		int n = str.length();
		n--;
		for (int i = 2, j = 0; i <= n; i++) {
			while (j && str[i] != str[j + 1])j = ne[j];
			if (str[i] == str[j + 1])j++;
			ne[i] = j;
		}
		int r = n - ne[n];
		int ans = n % r ? 1 : n / r;
		printf("%d %d %d %d\n", mn, ans, mx, ans);
	}
	return 0;
}

更多推荐

服务器资源监控工具Nmon工具搭建教程

nmon是IBM公司推出的一款免费性能监控工具,可以时时监控服务器资源,还可以定时监控服务器资源,并生成数据文件,记录服务器的资源消耗情况操作步骤:下载地址:https://nmon.sourceforge.net/pmwiki.php?n=Site.Download1,通过ssh工具连接服务器2,进入usr目录下创建

IP模块组装网络包及转发网络包链路

目录引言网络包网络包的组成​编辑网络包的转发转发设备大致流程​编辑ip模块发送网络包添加网络包的头部控制信息ip头部中添加发送方ip地址路由表查找规则​编辑添加协议号添加mac头部​编辑arp协议转换ip地址为mac地址​编辑arp缓存arp缓存失效​编辑ip模块对应的发送接受发送接受职责界定引言之前协议栈系列的文章讲

《Linux高性能服务器编程》--TCP/IP协议族

目录1--TCP/IP协议族2--数据链路层3--网络层4--传输层5--应用层6--封装和分用7--ARP协议的工作原理1--TCP/IP协议族TCP/IP协议族是一个四层协议系统,自底而上分别是数据链路层、网络层、传输层和应用层;2--数据链路层数据链路层两个常用协议:ARP协议(地址解析协议)和RARP协议(逆地

分析数组,结构体在反汇编中存储

本文会在IDA中分析数组,结构体在内存中的存储目录IDA分析数组存储IDA分析结构体存储传递参数的方式IDA分析数组存储测试代码如下:/************************************************************************//*@Author:玄都大法师/*@D

Gateway网关

网关GateWay官方文档:https://docs.spring.io/spring-cloud-gateway/docs/3.1.2/reference/html/#gateway-how-it-works核心概念路由:网关的核心数据结构,定义了网关如何处理请求.一条路由信息包含路由的唯一标识ID,目的地URI,一

驱动开发,基于gpio子系统编写LED灯的驱动,亮灭控制

1.gpio子系统介绍一个芯片厂商生产出芯片后会给linux提供一个当前芯片中gpio外设的驱动,我们当前只需要调用对应的厂商驱动即可完成硬件的控制。而linux内核源码中的gpio厂商驱动有很多,这里linux内核对厂商驱动做了一些封装,提供了一系列的API,我们在自己编写的设备驱动中只需要调用这些API即可访问对应

redis 集群(cluster)

1.前言我们知道,在Web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务(主存分离、快速容灾技术)还需要考虑数据容量的扩展,数据安全不会丢失等。在Redis中

大数据时代下统计数据质量的影响因素

统计工作是为政府提供国民经济运行信息的重要手段,将大数据应用于统计工作是社会发展饿必然趋势。一、内涵在数字化时代和数字经济的飞速发展,“数据”已经被认定为一种新的生产要素,并且发挥着重要作用。数据质量的高低直接影响数据价值的高低。数据质量,是指在业务环境下,数据符合数据消费者的使用者目的,能够满足业务场景具体需求的程度

132.【MySQL_进阶】

MySQL_进阶(一)、存储引擎1.MySQL体系结构(1).连接层(2).服务层(3).引擎层(4).存储层2.存储引擎简介(1).查看某张表的数据引擎(2).展示此版本支持的所有存储引擎(3).创建表my_myisam,并指定MyIASM存储引擎(4).存储引擎示列3.存储引擎_Innodb(1).Innodb介绍

赛宁党支部赴延安开展革命旧址学习主题党日活动

为深入学习贯彻新时代中国特色社会主义思想和中共二十大精神,不断提升党支部成员综合素质和业务能力,2023年9月,赛宁公司党支部组织北京、南京、广州等三地部分党员及入党积极分子开展了“革命旧址学习”主题党日活动,深入寻访延安革命纪念馆、杨家岭、枣园革命旧址等红色基地,重温入党誓词,感悟辉煌历史,凝聚前进力量。“走进革命纪

K8S-Pod 进阶

Pod进阶一、资源限制(业务cpu内存)1.定义2.Pod和容器的资源请求和限制3.CPU资源单位4.内存资源单位5.示例二、健康检查:又称为探针(Probe)1.定义2.探针的三种规则:3.Probe支持三种检查方法4.示例三、扩展1.pod的状态2.Container生命周期四、总结1.资源限制2.Pod容器探针3

热文推荐