【spoj1812】Longest Common Substring II 【SAM】

来源:互联网 发布:java 读取gz压缩文件 编辑:程序博客网 时间:2024/06/11 07:18

呵呵……

#include<bits/stdc++.h>using namespace std;const int maxn=100002;struct node{    node *f,*ch[26];    int len,ml,nl;}pool[maxn*2],*cur=pool,*tail=pool,*init=pool,*b[maxn<<1];void add(int c,int len){    node *p=tail,*np=++cur;    tail=np;    np->len=len;    np->ml=0x1f1f1f1f;    for(;p&&!p->ch[c];p=p->f) p->ch[c]=np;    if(!p) np->f=init;    else{        if(p->ch[c]->len==p->len+1) np->f=p->ch[c];        else{            node *q=p->ch[c],*nq=++cur;            *nq=*q;            nq->len=p->len+1;            q->f=np->f=nq;            for(;p&&p->ch[c]==q;p=p->f) p->ch[c]=nq;        }    }}void walk(char *s){    int now=0,c;node *x=init;    for(;*s;++s){        c=*s-'a';        if(x->ch[c]) now++,x=x->ch[c];        else{            while(x&&!x->ch[c]) x=x->f;            if(!x) now=0,x=init;            else now=x->len+1,x=x->ch[c];        }        if(now>x->nl) x->nl=now;    }}int w[maxn];char str[maxn];int main(){    gets(str);    int i=0,tot,l=strlen(str);    for(char *c=str;*c;c++) add(*c-'a',++i);    tot=cur-pool;    for(i=1;i<=tot;++i) w[pool[i].len]++;    for(i=1;i<=l  ;++i) w[i]+=w[i-1];    for(i=1;i<=tot;++i) b[w[pool[i].len]--]=pool+i;    while(scanf("%s",str)==1){        walk(str);        for(i=tot;i;--i){            node *x=b[i];            if(x->nl<x->ml) x->ml=x->nl;            if(x->f&&x->f->nl<x->nl){                x->f->nl=x->nl;                if(x->f->nl>x->f->len) x->f->nl=x->f->len;            }            x->nl=0;        }    }    int ans=0;    for(node *x=pool+1;x<=cur;++x) if(x->ml>ans) ans=x->ml;    printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击