看的《后缀数组——处理字符串的有力工具》这篇论文,在那里这道题是用后缀数组实现的,复杂度为$O(nlogn)$,很明显长度为$2×10^6$的数据会TLE,所以必需得用复杂度为$O(n)$的KMP算法。第一次写KMP,我好弱啊QAQ
KMP:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 2000003;
char s[N];
int p[N], j, n, i;
int main() {
while (scanf("%s", s + 1), s[1] != '.') {
j = 0; n =strlen(s + 1); p[1] = 0;
for(i = 2; i <= n; ++i) {
while (j && s[j + 1] != s[i]) j = p[j];
if (s[j + 1] == s[i]) ++j;
p[i] = j;
}
printf("%d\n", n % (n - p[n]) == 0 ? n / (n - p[n]) : 1);
}
return 0;
}
TLE的后缀数组做法:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 2000003;
int t1[N], t2[N], c[N];
void st(int *x, int *y, int *sa, int n, int m) {
int i;
for(i = 0; i < m; ++i) c[i] = 0;
for(i = 0; i < n; ++i) ++c[x[y[i]]];
for(i = 1; i < m; ++i) c[i] += c[i - 1];
for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
}
void mkhz(int *a, int *sa, int n, int m) {
int i, j, p, *x = t1, *y = t2, *t;
for(i = 0; i < n; ++i) x[i] = a[i], y[i] = i;
st(x, y, sa, n, m);
for(j = 1, p = 1; p < n; j <<= 1, m = p) {
for(i = n - j, p = 0; i < n; ++i) y[p++] = i;
for(i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
st(x, y, sa, n, m);
for(t = x, x = y, y = t, x[sa[0]] = 0, p = 1, i = 1; i < n; ++i)
x[sa[i]] = y[sa[i]] == y[sa[i - 1]] && y[sa[i] + j] == y[sa[i - 1] + j] ? p - 1 : p++;
}
}
void mkh(int *r, int *sa, int *rank, int *h, int n) {
int k = 0, i, j;
for(i = 1; i <= n; ++i) rank[sa[i]] = i;
for(i = 1; i <= n; h[rank[i++]] = k)
for(k ? --k : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; ++k);
}
char s[N];
int a[N], sa[N], rank[N], h[N], n, minn[N];
void mkmin() {
int pos = rank[1]; minn[pos] = h[pos];
for(int i = pos; i > 1; --i)
minn[i - 1] = min(minn[i], h[i]);
for(int i = pos + 1; i <= n; ++i)
minn[i] = min(minn[i - 1], h[i]);
}
void Qhz() {
int sq = sqrt((double)n);
for(int i = 1; i <= sq; ++i)
if (n % i == 0 && minn[rank[1 + i]] == n - i)
{printf("%d\n", n / i); return;}
puts("1");
}
int main() {
while (scanf("%s", s + 1), s[1] != '.') {
n = strlen(s + 1);
for(int i = 1; i <= n; ++i)
a[i] = s[i];
mkhz(a, sa, n + 1, 256);
mkh(a, sa, rank, h, n);
mkmin();
Qhz();
}
return 0;
}
呜呜呜~