• POJ-1509 Glass Beads


    题意:求一个字符串的最小表示的开始下标。

    分析:其实有一个O(N)的算法专门来解决这个问题,并且实现非常简单,不过后缀自动机同样能够解决这个问题。首先把这个串重复两次,然后从前往后一一将字符加入到后缀自动机中,最后从根开始向下遍历串的长度层即可。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 using namespace std;
     7 const int MAXN=10000+10;
     8 char str[MAXN];
     9 struct SAM{
    10     struct State{
    11         int ch[26];
    12         int link,len;
    13         void init(){
    14             link=-1;
    15             len=0;
    16             memset(ch,0xff,sizeof(ch));
    17         }
    18     }st[MAXN<<1];
    19     int size,last;
    20     void init(){
    21         size=last=0;
    22         st[size++].init();
    23     }
    24     int newst(){
    25         st[size].init();
    26         return size++;
    27     }
    28     void add(int c){
    29         int end=newst();
    30         int p=last;
    31         st[end].len=st[last].len+1;
    32         for(;p!=-1 && st[p].ch[c] == -1;p=st[p].link)
    33             st[p].ch[c]=end;
    34         if(p == -1) st[end].link=0;
    35         else {
    36             int nxt=st[p].ch[c];
    37             if(st[p].len+1 == st[nxt].len) st[end].link=nxt;
    38             else {
    39                 int clone=newst();
    40                 st[clone]=st[nxt];
    41                 st[clone].len=st[p].len+1;
    42                 st[end].link=st[nxt].link=clone;
    43                 for(;p!=-1 && st[p].ch[c]==nxt;p=st[p].link)
    44                     st[p].ch[c]=clone;
    45             }
    46         }
    47         last=end;
    48     }
    49 }sam;
    50 
    51 int main(){
    52     int T;
    53     scanf("%d",&T);
    54     while(T--){
    55         sam.init();
    56         scanf("%s",str);
    57         int len=strlen(str);
    58         for(int i=0;i<len*2;i++){
    59             sam.add(str[i%len]-'a');
    60         }
    61         int p=0;
    62         for(int i=0;i<len;i++){
    63             for(int j=0;j<26;j++){
    64                 if(sam.st[p].ch[j] != -1){
    65                     p=sam.st[p].ch[j];
    66                     break;
    67                 }
    68             }
    69         }
    70         printf("%d
    ",sam.st[p].len-len+1);
    71     }
    72     return(0);
    73 }
  • 相关阅读:
    Python 如何安装、使用pip
    关于防范短信诈骗-贷款方向
    YouTube视频下载解析网站
    压力大导致你的Logstash重发消息吗?
    入职第一件事情
    监控多文件夹目录变化,python,win32
    https://pypi.org/project/watchdog/#files
    UVM_COOKBOOK学习【UVM基础】
    UVM实用技巧【二】
    UVM实用技巧【一】
  • 原文地址:https://www.cnblogs.com/KCkowk/p/6510254.html
Copyright © 2020-2023  润新知