您的位置:首页 > 其它

spoj1812 Longest Common Substring II( 后缀自动机 )

2015-11-17 22:04 549 查看
贴个代码...

---------------------------------------------------------------------

#include<cstdio>#include<cstring>#include<algorithm> using namespace std; const int maxn = 200009;const int cn = 26; struct Node { Node *fa, *ch[cn]; int len, Min, Max; void upd() { Min = min(Min, Max); }} pool[maxn], *pt, *root, *last; void upd(Node* &t, int &v) { t->Max = max(t->Max, v);} Node* newNode(int v) { pt->fa = NULL; pt->len = v; memset(pt->ch, 0, sizeof pt->ch); return pt++;} void SAM_init() { pt = pool; root = last = newNode(0);} void Extend(int c) { Node *p = last, *np = newNode(p->len + 1); for(; p && !p->ch[c]; p = p->fa) p->ch[c] = np; if(!p) np->fa = root; else { Node* q = p->ch[c]; if(p->len + 1 == q->len) np->fa = q; else { Node* nq = newNode(p->len + 1); memcpy(nq->ch, q->ch, sizeof q->ch); nq->fa = q->fa; q->fa = np->fa = nq; for(; p && p->ch[c] == q; p = p->fa) p->ch[c] = nq; } } last = np;} char s[maxn]; void SAM_build() { scanf("%s", s); for(int i = 0, n = strlen(s); i < n; i++) Extend(s[i] - 'a');} bool work() { if(scanf("%s", s) == -1) return false; for(Node* t = root; t != pt; t++) t->Max = 0; int n = strlen(s); Node* t = root; for(int i = 0, lth = 0; i < n; i++) { int c = s[i] - 'a'; if(t->ch[c]) upd(t = t->ch[c], ++lth); else { for(; t && !t->ch[c]; t = t->fa); if(!t) t = root, lth = 0; else lth = t->len + 1, upd(t = t->ch[c], lth); } } for(Node* o = pt; --o != pool; ) upd(o->fa, o->Max); for(Node* o = pt; --o; ) { o->upd(); if(o == pool) break; } return true;} int main() { SAM_init(); SAM_build(); for(Node* t = root; t != pt; t++) t->Min = t->len; while(work()); int ans = 0; for(Node* t = root; t != pt; t++) ans = max(ans, t->Min); printf("%d\n", ans); return 0;}---------------------------------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: