zoukankan      html  css  js  c++  java
  • 字符串(后缀自动机):COGS 2399. 循环同构

      这道题直接看代码吧。

     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
    ",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 }
  • 相关阅读:
    dubbo springcloud区别
    rpc
    centos7 安装docker
    vibox安装
    知识点
    spring cloud
    微服务设计原则
    工具类
    xss--知识点
    java基础--注解
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5697265.html
Copyright © 2011-2022 走看看