1. 程式人生 > >廣義後綴自動機

廣義後綴自動機

-s insert swap != air urn wap cstring pre

坑,準備寫寫對SAM和trie上SAM的一些個人理解(咕咕咕警告)

有沒有哪位神仙有lyy2015年的國家集訓隊論文……跪求

話說多串SAM和trie上SAM貌似不太一樣?

模板

【BZOJ3473】字符串

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #include<set
> 8 #define inf 2147483647 9 #define eps 1e-9 10 #define mp make_pair 11 using namespace std; 12 typedef long long ll; 13 typedef double db; 14 struct edge{ 15 int v,next; 16 }a[200001]; 17 int n,k,tote=0,tot=1,last=1,rt=1,son[200001][26],fa[200001],mx[200001],num[200001],head[200001]; 18 ll ans; 19 set<int
>siz[200001]; 20 string s[100001]; 21 void add(int u,int v){ 22 //printf("Added: %d %d\n",u,v); 23 a[++tote].v=v; 24 a[tote].next=head[u]; 25 head[u]=tote; 26 } 27 void extend(int ch,int id){ 28 int p=last,np=++tot; 29 mx[np]=mx[p]+1; 30 siz[np].insert(id); 31 for(;p&&!son[p][ch];p=fa[p])son[p][ch]=np;
32 if(!p)fa[np]=rt; 33 else{ 34 int q=son[p][ch]; 35 if(mx[q]==mx[p]+1)fa[np]=q; 36 else{ 37 int nq=++tot; 38 mx[nq]=mx[p]+1; 39 memcpy(son[nq],son[q],sizeof(son[q])); 40 fa[nq]=fa[q]; 41 fa[q]=fa[np]=nq; 42 for(;p&&son[p][ch]==q;p=fa[p])son[p][ch]=nq; 43 } 44 } 45 last=np; 46 } 47 void dfs(int u){ 48 for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){ 49 int v=a[tmp].v; 50 dfs(v); 51 if(siz[u].size()<siz[v].size())swap(siz[u],siz[v]); 52 for(set<int>::iterator it=siz[v].begin();it!=siz[v].end();it++){ 53 siz[u].insert(*it); 54 } 55 } 56 num[u]=siz[u].size(); 57 } 58 int main(){ 59 memset(head,-1,sizeof(head)); 60 scanf("%d%d",&n,&k); 61 if(k>n){ 62 for(int i=1;i<=n;i++)puts("0"); 63 return 0; 64 } 65 for(int i=1;i<=n;i++){ 66 cin>>s[i]; 67 for(int j=0,jj=s[i].length();j<jj;j++){ 68 extend(s[i][j]-a,i); 69 } 70 last=rt; 71 } 72 for(int i=2;i<=tot;i++){ 73 add(fa[i],i); 74 } 75 dfs(rt); 76 for(int i=1;i<=n;i++){ 77 ans=0; 78 for(int j=0,jj=s[i].length(),nw=rt;j<jj;j++){ 79 nw=son[nw][s[i][j]-a]; 80 for(;num[nw]<k;nw=fa[nw]); 81 ans+=mx[nw]; 82 } 83 printf("%lld\n",ans); 84 } 85 return 0; 86 }

廣義後綴自動機