这题有毒……
原本只是想复习下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(""); } }
时间: 2024-11-10 07:28:56