【后缀自动机】 SPOJ LCS

来源:互联网 发布:选择排序java代码 编辑:程序博客网 时间:2024/05/16 10:14

将A建立成后缀自动机,后缀自动机的任意一个节点都表示若干个A的字串,让B在后缀自动机上匹配,不能匹配就沿着fa指针转移。。。

#include <iostream>#include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits>#include <cstdlib>#include <cmath>#include <time.h>#define maxn 500005#define maxm 10005#define eps 1e-7#define mod 1000000007#define INF 0x3f3f3f3f#define PI (acos(-1.0))#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R#define pii pair<int, int>#pragma comment(linker, "/STACK:16777216")typedef long long LL;typedef unsigned long long ULL;//typedef int LL;using namespace std;LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}// headstruct node{int len;node *fa, *next[26];}*tail, *root, pool[maxn], *last;char a[maxn];char b[maxn];node* newnode(int len){tail->len = len;tail->fa = 0;memset(tail->next, 0, sizeof tail->next);return tail++;}void init(){tail = pool;root = newnode(0);last = root;}void add(int c){node *p = last, *np = newnode(last->len + 1);last = np;for(; p && !p->next[c]; p = p->fa) p->next[c] = np;if(!p) np->fa = root;else {node *q = p->next[c];if(p->len + 1 == q->len) np->fa = q;else {node *nq = newnode(q->len);*nq = *q;nq->len = p->len + 1;np->fa = q->fa = nq;for(; p && p->next[c] == q; p = p->fa) p->next[c] = nq;}}}void work(){init();scanf("%s%s", a, b);int len = strlen(a);for(int i = 0; i < len; i++) add(a[i] - 'a');len = strlen(b);int ans = 0, res = 0;node *p = root;for(int i = 0; i < len; i++) {int c = b[i] - 'a';if(p->next[c]) res++, p = p->next[c];else {for(; p && !p->next[c]; p = p->fa);if(!p) res = 0, p = root;else res = p->len + 1, p = p->next[c];}ans = max(ans, res);}printf("%d\n", ans);}int main(){work();return 0;}


0 0