SPOJ

来源:互联网 发布:淘宝客 traceid 编辑:程序博客网 时间:2024/06/07 05:23

SPOJ - 1811

输入两个字符串A和B,求最长公共子串,构造字符串A的后缀自动机,然后将字符串B从头开始在后缀自动机中匹配,能匹配到则继续往下,cnt++, 否则,一直往前跳,一直到找到能匹配该字符的后缀,或者跳回root.

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>#include <bitset>#define INF 0x3f3f3f3f#define eps 1e-6#define PI 3.1415926#define mod 1000000009#define base 2333using namespace std;typedef long long LL;const int maxn = 3e5 + 10;const int maxx = 1e3 + 10;inline void splay(int &v) {    v=0;char c=0;int p=1;    while(c<'0' || c >'9'){if(c=='-')p=-1;c=getchar();}    while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}    v*=p;}struct Node {    Node *pre, *nxt[26];    int step;    void Clear() {        step = 0;        pre = NULL;        memset(nxt, NULL, sizeof(nxt));    }} *root, *last;Node st[maxn<<1], *cur;char str1[maxn], str2[maxn];void init() {    cur = st;    root = last = cur++;    root->Clear();}void extend(int w) {    Node *np = cur++, *p = last;    np->Clear();    np->step = p->step+1;    while(p && !p->nxt[w])        p->nxt[w] = np, p = p->pre;    if(p == NULL)        np->pre = root;    else {        Node *q = p->nxt[w];        if(q->step == p->step+1)            np->pre = q;        else {            Node *nq = cur++;            memcpy(nq->nxt, q->nxt, sizeof(q->nxt));            nq->pre = q->pre;            nq->step = p->step+1;            np->pre = q->pre = nq;            while(p && p->nxt[w] == q)                p->nxt[w] = nq, p = p->pre;        }    }    last = np;}void solve() {    while(scanf("%s%s", str1, str2) != EOF) {        init();        int len1 = strlen(str1), len2 = strlen(str2);        for(int i = 0; i < len1; i++)            extend(str1[i]-'a');        int cnt = 0, ans = 0;        Node *now = root;        for(int i = 0; i < len2; i++) {            int x = str2[i]-'a';            if(now->nxt[x]) {                now = now->nxt[x];                cnt++;            }            else {                while(now && !now->nxt[x])                    now = now->pre;                if(now == NULL) {                    now = root;                    cnt = 0;                }                else {                    cnt = now->step+1;                    now = now->nxt[x];                }            }            if(cnt > ans)                ans = cnt;        }        printf("%d\n", ans);    }}int main() {    //srand(time(NULL));    //freopen("kingdom.in","r",stdin);    //freopen("kingdom.out","w",stdout);    solve();}