首页 > 代码库 > 【hihocoder】sam1-基本概念

【hihocoder】sam1-基本概念

这题有毒……

原本只是想复习下sam,于是写……

后来发现自己傻了不知道怎么维护endpos……

一气之下直接kmp拉倒,mdzz

 

UPD:现在我好像会维护endpos了……

 

#include<bits/stdc++.h>
#define N 100010
using namespace std;
int a[N],l,n,b[N],t,nxt[N];
struct Suffix_AutoMaton{
    int cnt,last,ch[N][26],l[N],r[N],fa[N];
    void ins(int c,int pos){
        int p=last,np=++cnt;last=np;l[np]=pos;r[np]=pos;
        for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
        if(!p)fa[np]=1;
        else{
            int q=ch[p][c];
            if(l[p]+1==l[q])fa[np]=q,r[q]=pos;
            else{
                int nq=++cnt;l[nq]=l[p]+1;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q];fa[q]=fa[np]=nq;r[nq]=pos;
                for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq;
            }
        }
    }
    Suffix_AutoMaton(){last=cnt=1;}
    void build(int *a,int n){for(int i=1;i<=n;i++)ins(a[i],i);}
    inline int get(int *a,int n){
        int k=1;for(int i=1;i<=n;i++)k=ch[k][a[i]];
        return k;
    }
}sam;
inline char read(){
    char c=getchar();
    while(c<a||c>z)c=getchar();
    return c;
}
int main(){
    char c=read();
    while(c>=a&&c<=z)a[++l]=c-a,c=getchar();
    sam.build(a,l);scanf("%d",&n);
    while(n--){
        t=0;char c=read();
        while(c>=a&&c<=z)b[++t]=c-a,c=getchar();
        int s=sam.get(b,t);
        for(int j=sam.r[s]-sam.l[sam.fa[s]];j<=sam.r[s];j++)printf("%c",a[j]+a);putchar( );
        for(int j=sam.r[s]-sam.l[s]+1;j<=sam.r[s];j++)printf("%c",a[j]+a);
        nxt[1]=0;
        for(int i=2,j=0;i<=t;i++){
            while(j&&b[i]!=b[j+1])j=nxt[j];
            j+=b[i]==b[j+1];
            nxt[i]=j;
        }
        for(int i=1,j=0;i<=l;++i){
            while(j&&a[i]!=b[j+1])j=nxt[j];
            if(a[i]==b[j+1])++j;
            if(j==t)printf(" %d",i),j=nxt[j];
        }
        puts("");
    }
}

 

【hihocoder】sam1-基本概念