标签:
这道题直接看代码吧。
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 }
标签:
原文地址:http://www.cnblogs.com/TenderRun/p/5697265.html