zoukankan      html  css  js  c++  java
  • [POJ1509]Glass Beads 后缀自动机 最小循环串

    题目链接:http://poj.org/problem?id=1509

    题目意思就是求循环字符串的最小表示。

    我们用字符串S+S建立SAM,然后从root开始走n步,每次尽量选最小的。

    由于 SAM 可以接受 SS 所有的子串,而字典序最小的字符串也必定是 SS 的子串,因此按照上面的规则移动就可以找到一个字典序最小的子串。

    这里的right等价类的len显然可以直接扩展到串首,于是开始的位置就是T[o].len-n+1。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 struct State{
     6     int ch[26],fa,len;
     7     void init(){
     8         fa=-1;
     9         len=0;
    10         memset(ch,-1,sizeof(ch));
    11     }
    12 }T[50010];
    13 char s[10010];
    14 int cnt=0,la;
    15 void Extend(int c){
    16     int end=++cnt,tmp=la;
    17     T[end].init();
    18     T[end].len=T[tmp].len+1;
    19     while(tmp!=-1&&T[tmp].ch[c]==-1){
    20         T[tmp].ch[c]=end;
    21         tmp=T[tmp].fa;
    22     }
    23     if(!~tmp) T[end].fa=0;
    24     else{
    25         int ne=T[tmp].ch[c];
    26         if(T[tmp].len+1==T[ne].len) T[end].fa=ne;
    27         else{
    28             int np=++cnt;
    29             T[np].init();
    30             T[np]=T[ne];
    31             T[np].len=T[tmp].len+1;
    32             T[end].fa=T[ne].fa=np;
    33             while(tmp!=-1&&T[tmp].ch[c]==ne){
    34                 T[tmp].ch[c]=np;
    35                 tmp=T[tmp].fa;
    36             }
    37         }
    38     }
    39     la=end;
    40 }
    41 int main(){
    42     int Test;
    43     scanf("%d",&Test);
    44     while(Test--){
    45         cnt=0;
    46         la=0;
    47         T[0].init();
    48         scanf("%s",s);
    49         int n=strlen(s);
    50         for(int i=0;i<n;i++) Extend(s[i]-'a');
    51         for(int i=0;i<n;i++) Extend(s[i]-'a');
    52         int o=0;
    53         for(int i=0;i<n;i++)
    54             for(int j=0;j<26;j++)
    55                 if(~T[o].ch[j]){
    56                     o=T[o].ch[j];
    57                     break;
    58                 }
    59         printf("%d
    ",T[o].len-n+1);
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    【总结】Centos中,Kerberos安装
    Go语言mgo
    Go语言mgo
    理解 Serenity,Part-1:深度抽象
    ZCash零知识证明
    零知识证明(Zero-Knowledge Proof)原理详解:非交互式证明实现自动验证防止作假
    tf.shape(x)、x.shape、x.get_shape()函数解析(最清晰的解释)
    Java生成(m.n)之间的随机数
    tf.cond()函数解析(最清晰的解释)
    OpenStack Blazar 架构解析与功能实践
  • 原文地址:https://www.cnblogs.com/halfrot/p/7445437.html
Copyright © 2011-2022 走看看