题目描述
原题来自:POJ 2406
给定若干个长度 \le 10^6 的字符串,询问每个字符串最多是由多少个相同的子字符串重复连接而成的。如:ababab 则最多有 3 个 ab 连接而成。
输入格式
输入若干行,每行有一个字符串。特别的,字符串可能为 . 即一个半角句号,此时输入结束。
样例
输入
abcd
aaaa
ababab
.
输出
1
4
3
数据范围与提示
字符串长度 ≤ 1 0 6 \le 10^6 ≤106。
哈希函数做法
大致思路
练KMP,模式串如果第i位与文本串第j位不匹配,就要回到第p[i]位继续与文本串第j位匹配,则模式串第一位到第p[n]与模式串第(n-p[n])位到第n位是匹配的。所以如果n%(n-p[n])==0,则存在重复子串,长度为n-p[n],子串循环了n/(n-p[n])。反之,则没有重复子串,主串自己与自己匹配,输出1。
#include<bits/stdc++.h>
using namespace std;
const int N=1e8;
int len,p[N],ans;
char a[N];
bool flag=0;
void pre(){
int j=0;p[1]=0;
for(int i=1;i<len;i++){
while(j>0&&a[i+1]!=a[j+1])j=p[j];
if(a[i+1]==a[j+1])j++;
p[i+1]=j;
}
}
int main(){
while(scanf("%s",a+1)){
len=strlen(a+1);
if(a[1]=='.')break;
pre();
if(len%(len-p[len])==0){
cout<<len/(len-p[len])<<endl;
}
else cout<<"1"<<endl;
}
return 0;
}
/*abcd
aaaa
ababab*/