码迷,mamicode.com
首页 > 其他好文 > 详细

字符串(后缀自动机):COGS 2399. 循环同构

时间:2016-07-22 23:00:59      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

技术分享

技术分享

  这道题直接看代码吧。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int maxn=2000010;
 6 int fa[maxn],len[maxn],rit[maxn],w[maxn],sa[maxn];
 7 int n,Q,cnt,lst,ch[maxn][26],vis[maxn];
 8 char s[maxn];
 9 struct SAM{
10     SAM(){
11         memset(fa,0,sizeof(fa));
12         memset(len,0,sizeof(len));
13         memset(rit,0,sizeof(rit));
14         cnt=lst=1;
15     }
16     
17     void Insert(int c){
18         int p=lst,np=lst=++cnt;len[np]=len[p]+1;
19         while(p&&!ch[p][c])ch[p][c]=np,p=fa[p];
20         if(!p)fa[np]=1;
21         else{
22             int q=ch[p][c];
23             if(len[p]+1==len[q])fa[np]=q;
24             else{
25                 int nq=++cnt;len[nq]=len[p]+1;
26                 memcpy(ch[nq],ch[q],sizeof(ch[q]));
27                 fa[nq]=fa[q];fa[q]=fa[np]=nq;
28                 while(ch[p][c]==q)ch[p][c]=nq,p=fa[p];
29             }
30         }
31     }
32     
33     void Prepare(){
34         //rit[1]=1;
35         for(int i=1,p=1;i<=n;i++)
36             rit[p=ch[p][s[i]-a]]+=1;
37         for(int i=1;i<=cnt;i++)w[len[i]]+=1;
38         for(int i=1;i<=cnt;i++)w[i]+=w[i-1];
39         for(int i=1;i<=cnt;i++)sa[--w[len[i]]]=i;
40         for(int i=cnt;i;i--)rit[fa[sa[i]]]+=rit[sa[i]];
41     }
42     
43     void Solve(int tim){
44         scanf("%s",s+1);n=strlen(s+1);
45         for(int i=1;i<=n;i++)s[n+i]=s[i];
46         int p=1,ans=0,l=0;
47         for(int i=1,c;i<2*n;i++){
48             c=s[i]-a;
49             while(p!=1&&!ch[p][c])
50                 {p=fa[p];l=len[p];}
51             if(!ch[p][c])l=0;
52             else{p=ch[p][c];l+=1;}
53             
54             if(l>=n){
55                 while(len[fa[p]]>=n)p=fa[p],l=len[p];
56                 if(vis[p]!=tim)vis[p]=tim,ans+=rit[p];
57             }
58         }
59         printf("%d\n",ans);
60     }
61 }sam;
62 int main(){
63     freopen("rotate.in","r",stdin);
64     freopen("rotate.out","w",stdout);
65     scanf("%s%d",s+1,&Q);n=strlen(s+1);
66     for(int i=1;i<=n;i++)sam.Insert(s[i]-a);
67     sam.Prepare();while(Q--)sam.Solve(Q+1);
68     return 0;
69 }

 

字符串(后缀自动机):COGS 2399. 循环同构

标签:

原文地址:http://www.cnblogs.com/TenderRun/p/5697265.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!