此题为最简单的后缀自动机的应用。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 10010;
struct SamNode {
int ch[26];
int par, len;
void Init() {
par = -1;
len = 0;
memset(ch, -1, sizeof(ch));
}
};
class SAM
{
public:
void Init() {
tot = 0;
last = 0;
sn[0].Init();
}
void Add(int c) {
int end = NewNode();
int tmp = last;
sn[end].len = sn[last].len + 1;
for ( ; tmp != -1 && sn[tmp].ch[c] == -1; tmp = sn[tmp].par) {
sn[tmp].ch[c] = end;
}
if (tmp == -1) {
sn[end].par = 0;
} else {
int nxt = sn[tmp].ch[c];
if (sn[tmp].len + 1 == sn[nxt].len) {
sn[end].par = nxt;
} else {
int np = NewNode();
sn[np] = sn[nxt];
sn[np].len = sn[tmp].len + 1;
sn[end].par = sn[nxt].par = np;
for ( ; tmp != -1 && sn[tmp].ch[c] == nxt; tmp = sn[tmp].par) {
sn[tmp].ch[c] = np;
}
}
}
last = end;
}
int tot;
int last;
SamNode sn[maxn*4];
int NewNode() {
sn[++tot].Init();
return tot;
}
};
int t, n;
char s[maxn];
SAM sam;
int main()
{
scanf("%d", &t);
while (t--) {
scanf("%s", s);
sam.Init();
n = strlen(s);
for (int i = 0; i < n; ++i) {
sam.Add(s[i] - 'a');
}
for (int i = 0; i < n; ++i) {
sam.Add(s[i] - 'a');
}
int now = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < 26; ++j) {
if (sam.sn[now].ch[j] != -1) {
now = sam.sn[now].ch[j];
break;
}
}
}
printf("%d\n", sam.sn[now].len - n + 1);
}
return 0;
}