OJ-Problems-Source/HDOJ/4270_autoAC.cpp

98 lines
2.5 KiB
C++

#include <cstdio>
#include <cstring>
const int MAXN = 200005;
struct SAMNode {
SAMNode *f, *ch[26];
int len;
bool *d;
int pos;
int v;
};
SAMNode *root, *last;
int p_cnt, d_cnt, seq_len, v_id;
SAMNode pool[MAXN*2];
bool is_d[MAXN*2];
char str[MAXN];
SAMNode *seq[MAXN];
bool is_del(SAMNode *x) {
return x == NULL || *x->d;
}
void append(char ch) {
int c = ch - 'a';
SAMNode *p = last, *np = pool + p_cnt++;
memset(np, 0, sizeof(*np));
np->pos = np->len = p->len + 1;
np->d = is_d + d_cnt++;
*np->d = false;
seq[seq_len = np->len] = np;
last = np;
for (; NULL != p && is_del(p->ch[c]); p = p->f) p->ch[c] = np;
if (NULL == p) {
np->f = root;
} else {
if (p->ch[c]->len == p->len + 1) {
np->f = p->ch[c];
} else {
SAMNode *q = p->ch[c], *nq = pool + p_cnt++;
*nq = *q;
nq->len = p->len + 1;
q->f = np->f = nq;
for (; NULL != p && p->ch[c] == q; p = p->f) p->ch[c] = nq;
}
}
}
void del(int len) {
while (len--) *seq[seq_len--]->d = true;
last = seq[seq_len];
}
int dfs_len;
int dfs(SAMNode *x, int l) {
if (l == dfs_len) return x->pos - l + 1;
if (x->v == v_id) return seq_len - l + 1;
for (int i = 0; i < 26; ++i) {
if (!is_del(x->ch[i])) {
return dfs(x->ch[i], l+1);
}
}
return x->len - l + 1;
}
int query(int len) {
++v_id;
for (SAMNode *p = last; p != root; p = p->f) p->v = v_id;
dfs_len = len;
int ret = dfs(root, 0);
return ret;
}
int main() {
while (EOF != scanf("%s", str)) {
root = last = pool;
memset(root, 0, sizeof(*root));
root->d = is_d;
is_d[0] = false;
p_cnt = 1;
d_cnt = 1;
v_id = 0;
seq[0] = root;
for (char *c = str; *c; ++c) append(*c);
int m, q, len;
scanf("%d", &m);
while (m--) {
scanf("%d", &q);
if (1 == q) {
scanf("%s", str);
for (char *c = str; *c; ++c) append(*c);
} else if (2 == q) {
scanf("%d", &len);
printf("%d\n", query(len));
} else if (3 == q) {
scanf("%d", &len);
del(len);
} else {
for(;;);
fprintf(stderr, "error cmd %d\n", q);
}
}
}
return 0;
}