zoukankan      html  css  js  c++  java
  • POJ 1509 Glass Beads 后缀自动机 模板 字符串的最小表示

    http://poj.org/problem?id=1509

    后缀自动机其实就是一个压缩储存空间时间(对节点重复利用)的储存所有一个字符串所有子串的trie树,如果想不起来长什么样子可以百度一下找个图回忆,从0开始到任意一个点的串都是字符串的子串。 有一些很好用的性质。

    字符串的最小表示就是把一个字符串首尾相连再从任意一个地方断开产生的字典序最小的字符串,这个题是求最小表示的开头字母在原字符串中的下标(从1开始)。

    具体看实现吧,没什么可以解释的地方。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 const int maxn=100010;
     9 char ch[maxn]={};
    10 int siz;
    11 int tot,la;
    12 struct nod{
    13     int sig[26];int f,len;
    14     void cle(){f=-1,len=0;memset(sig,-1,sizeof(sig));}
    15 }sam[maxn*2];
    16 void fir(){tot=0;la=0;sam[0].cle();}
    17 void add(int z){
    18     int x=++tot;sam[x].cle();
    19     int i=la;
    20     sam[x].len=sam[la].len+1;
    21     for(;i!=-1&&sam[i].sig[z]==-1;i=sam[i].f)
    22         sam[i].sig[z]=x;
    23     if(i==-1)sam[x].f=0;
    24     else{
    25         int nex=sam[i].sig[z];
    26         if(sam[i].len+1==sam[nex].len)sam[x].f=nex;
    27         else{
    28             int y=++tot;sam[y].cle();
    29             sam[y]=sam[nex];
    30             sam[y].len=sam[i].len+1;
    31             sam[x].f=sam[nex].f=y;
    32             for(;i!=-1&&sam[i].sig[z]==nex;i=sam[i].f){
    33                 sam[i].sig[z]=y;
    34               }
    35         }
    36     }la=x;
    37 }
    38 int main(){
    39     int T;scanf("%d",&T);
    40     while(T-->0){
    41         fir();
    42         scanf("%s",ch);siz=strlen(ch);
    43         for(int i=0;i<siz*2;++i)add(ch[i%siz]-'a');
    44         int p=0;
    45         for(int i=0;i<siz;i++){
    46             for(int j=0;j<26;j++){
    47                 if(sam[p].sig[j]!=-1){p=sam[p].sig[j];break;}
    48             }
    49         }
    50         printf("%d
    ",sam[p].len-siz+1);
    51     }
    52     return 0;
    53 }
    View Code

  • 相关阅读:
    hdu 4324(dfs)
    hdu 2376(求树上任意两点之间距离之和的平均值)
    hdu 3665(最短路)
    hdu 4463(最小生成树变形)
    hdu 2242(边双连通分量)
    hdu 2682(最小生成树)
    hdu 2444(二分图的判断以及求最大匹配)
    陶哲轩实分析命题6.4.12
    陶哲轩实分析习题8.3.4
    CantorBernsteinSchroeder定理的证明
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8531075.html
Copyright © 2011-2022 走看看