标签:
理解起来好困难啊QAQ
WIKIOI3160 求两个串的最长公共子串
见CLJppt
1 char s[maxn]; 2 struct sam 3 { 4 int n,last,cnt; 5 int go[maxn][26],l[maxn],fa[maxn]; 6 void add(int x) 7 { 8 int p=last,np=last=++cnt;l[np]=l[p]+1; 9 for(;p&&!go[p][x];p=fa[p])go[p][x]=np; 10 if(!p)fa[np]=1; 11 else 12 { 13 int q=go[p][x]; 14 if(l[p]+1==l[q])fa[np]=q; 15 else 16 { 17 int nq=++cnt;l[nq]=l[p]+1; 18 memcpy(go[nq],go[q],sizeof(go[q])); 19 fa[nq]=fa[q]; 20 fa[np]=fa[q]=nq; 21 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq; 22 } 23 } 24 } 25 void init() 26 { 27 last=cnt=1; 28 scanf("%s",s);int m=strlen(s); 29 for0(i,m-1)add(s[i]-‘a‘); 30 } 31 void solve() 32 { 33 scanf("%s",s);int m=strlen(s),now=1,t=0,ans=0; 34 for0(i,m-1) 35 { 36 int x=s[i]-‘a‘; 37 if(go[now][x])t++,now=go[now][x]; 38 else 39 { 40 while(now&&!go[now][x])now=fa[now]; 41 if(!now)t=0,now=1; 42 else t=l[now]+1,now=go[now][x]; 43 } 44 ans=max(ans,t); 45 } 46 printf("%d\n",ans); 47 } 48 }T; 49 int main() 50 { 51 T.init(); 52 T.solve(); 53 return 0; 54 }
BZOJ2555: SubString
正解是SAM+LCT,但出题人显然没有卡暴力。。。写了个暴力结果跑了rank4 233
犯了一个sb错就是没有更新lastQAQ
1 char s[2*maxn]; 2 int mask; 3 struct sam 4 { 5 int last,cnt,fa[maxn],go[maxn][26],l[maxn],r[maxn]; 6 sam(){last=cnt=1;} 7 void add(int x) 8 { 9 int p=last,np=++cnt;last=np;l[np]=l[p]+1; 10 for(;p&&!go[p][x];p=fa[p])go[p][x]=np; 11 if(!p)fa[np]=1; 12 else 13 { 14 int q=go[p][x]; 15 if(l[p]+1==l[q])fa[np]=q; 16 else 17 { 18 int nq=++cnt;l[nq]=l[p]+1; 19 memcpy(go[nq],go[q],sizeof(go[q])); 20 r[nq]=r[q]; 21 fa[nq]=fa[q]; 22 fa[q]=fa[np]=nq; 23 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq; 24 } 25 } 26 for(;np;np=fa[np])r[np]++; 27 } 28 void insert(char s[]) 29 { 30 int n=strlen(s),t=mask; 31 for0(i,n-1){mask=(mask*131+i)%n;swap(s[i],s[mask]);} 32 mask=t; 33 for0(i,n-1)add(s[i]-‘A‘); 34 } 35 void query(char s[]) 36 { 37 int n=strlen(s),now=1,t=mask; 38 for0(i,n-1){mask=(mask*131+i)%n;swap(s[i],s[mask]);} 39 for0(i,n-1)now=go[now][s[i]-‘A‘]; 40 mask=t^r[now]; 41 printf("%d\n",r[now]); 42 } 43 }T; 44 int main() 45 { 46 freopen("input.txt","r",stdin); 47 freopen("output.txt","w",stdout); 48 int Q=read(); 49 scanf("%s",s);int n=strlen(s);for0(i,n-1)T.add(s[i]-‘A‘); 50 while(Q--) 51 { 52 scanf("%s",s); 53 if(s[0]==‘A‘){scanf("%s",s);T.insert(s);} 54 else {scanf("%s",s);T.query(s);} 55 } 56 return 0; 57 }
标签:
原文地址:http://www.cnblogs.com/zyfzyf/p/4397216.html