您的位置:首页 > 其它

noi2015模板-后缀自动机

2015-07-16 22:33 274 查看
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std;

#define rep(i, l, r) for (int i = l; i <= r; i++)
#define REP(i, l, r) for (int i = l; i >= r; i--)
#define MAXN 200010

inline int read() {
int x = 0, f = 1; char ch = getchar();
while (ch<'0' || ch>'9') {if (ch == '-') f = -1; ch = getchar();}
while (ch>='0' && ch<='9') x = x*10 + ch - '0', ch = getchar();
return x*f;
}

struct SAM {
struct Node {
int ch[26], f, len;
void init() {
len = 0, f = -1;
memset(ch, 0xff, sizeof(ch));
}
} sn[MAXN];
int idx, last;

void init() {
idx = last = 0;
sn[idx++].init();
}

int newnode() {
sn[idx].init();
return idx++;
}

void add(int c) {
int end = newnode(), tmp = last;
sn[end].len = sn[last].len + 1;
while (tmp != -1 && sn[tmp].ch[c] == -1) sn[tmp].ch[c] = end, tmp = sn[tmp].f;
if (tmp == -1) sn[end].f = 0;
else {
int nxt = sn[tmp].ch[c];
if (sn[tmp].len + 1 == sn[nxt].len) sn[end].f = nxt;
else {
int np = newnode();
sn[np] = sn[nxt];
sn[np].len = sn[tmp].len + 1;
sn[end].f = sn[nxt].f = np;
while (tmp != -1 && sn[tmp].ch[c] == nxt) sn[tmp].ch[c] = np, tmp = sn[tmp].f;
}
}
last = end;
}
}sam;

int main() {
int T_T = read();
while (T_T--) {
sam.init();
char str[MAXN]; scanf("%s", str);
int len = strlen(str);
rep(i, 0, len*2-1) sam.add(str[i%len] - 'a');
int p = 0;
rep(i, 0, len-1) rep(j, 0, 25)
if (sam.sn[p].ch[j] != -1) {p = sam.sn[p].ch[j]; break;}
printf("%d\n", sam.sn[p].len - len + 1);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: