题面
题解
看数据范围,如果使用暴力,双重循环n2 ,字符串长度是1e6 ,肯定会超时,下面讲解正确解法
- 首先要知道KMP的 ne[i]=j 以i为终点的后缀和从1开始的前缀最大重合是j(蓝色部分的长度)
- 我们可以发现,区间1和区间2,3的字符串是相等的,然后继续划分,使 1 = 4 ,然后 自然 4 = 5 ,5 = 6 ,6 = 7 …一直这样划分,就可以划分出长度为 i -ne[i] 的区间 满足循环
- 循环长度已经确定,怎样保证它就是最小的呢(只有区间长度最小,才能划分出更多),如果这个长度不是最小,还可以更小,那么这个子字符串的ne[i]就会相应的增大,就互相矛盾
- 我们只需要判断这个循环的长度是否满足条件即可,循环区间肯定大于1个,所以长度肯定小于i,其次就是这个长度必须能被i整除
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n;
char p[N];
int ne[N];
int main() {
int t = 0;
while (cin >> n && n) {
for (int i = 1; i <= n; i++) cin >> p[i];
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;
}
cout << "Test case #" << ++t << endl;
for (int i = 2; i <= n; i++) {
int len=i-ne[i];
if(len!=i&&i%len==0){
cout<<i<<" "<<i/len<<endl;
}
}
cout << endl;
}
return 0;
}