Power Strings
题面翻译
题意简述:
求一个字符串由多少个重复的子串连接而成。
例如 ababab
由三个 ab
连接而成,abcd
由 abcd
由一个 abcd
连接而成。
输入格式
本题多组数据。
每一组数据仅有一行,这一行仅有一个字符串 s s s。
输入的结束标志为一个 .
。
输出格式
对于每一组数据,输出这组字符串由多少个重复的子串连接而成。
说明/提示
1 ≤ ∣ s ∣ ≤ 1 0 6 1\le |s|\le 10^6 1≤∣s∣≤106。
题目描述
输入格式
输出格式
样例 #1
样例输入 #1
abcd
aaaa
ababab
.
样例输出 #1
1
4
3
读题
采用hash做法,通过哈希值来判断字符串中是否存在重复子串,并求出重复子串的个数。
此题较优秀,笔者在此想分为两部分来谈论,具体分为总览
与分析
,当然,在阅读后有兴趣的读者可以通过网络,查阅相关资料(比如蓝书–《算法竞赛入门经典·训练指南》)。
1.总览
根据题目,很容易想到:
- 读入一个字符串,存储在数组
aa
中,作为主串。 - 检查是否为结束标志,即字符串以句号
'.'
开头。如果是,则退出程序;否则继续执行后续步骤。 - 计算输入字符串
aa
的长度,存储在变量n
中。 - 初始化哈希数组
h
,数组大小设为M
。 - 计算哈希数组
h
,其中h[i]
表示字符串aa
的前缀子串aa[1...i]
的哈希值。 - 进入循环遍历,枚举每个可能的重复模式长度
i
。 - 判断当前长度
i
是否能整除字符串长度n
,如果不能,则继续下一次循环。 - 计算模式串的哈希值
s
,即子串aa[1...i]
的哈希值。 - 调用
check
函数,检查字符串是否存在长度为i
的重复模式。check
函数使用哈希值进行匹配判断。 - 如果存在重复模式,则输出重复模式的个数,即字符串长度除以重复模式长度。
- 回到第 5 步,继续处理下一个输入字符串。
代码
#include<bits/stdc++.h>
using namespace std;
const int x=1311,M=1e7;
int a[M],b[M],h[M],f=0;
char aa[M],bb[M];
int n,s;
bool init(){
scanf("%s",aa+