后缀自动机)

来源:互联网 发布:画图软件solidworks 编辑:程序博客网 时间:2024/05/21 15:46
 

uva 719 - Glass Beads(后缀自动机)

分类: 后缀自动机 69人阅读 评论(0) 收藏 举报
后缀自动机

uva 719 - Glass Beads(后缀自动机)

题意:求循环同构的最小表示的起点。

解题思路:这题用后缀自动机来解,牛刀杀鸡啊,我只是写写模板。。构造好sam之后,按字典序,dfs遍历,当深度达到n时,就返回当前节点的val值(也就是它的len),记录为k,那么答案就是k-n+1。

[cpp] view plaincopyprint?
  1. #include<stdio.h>  
  2. #include<string.h>  
  3. #include<algorithm>  
  4. using namespace std ;  
  5.   
  6. const int maxn = 1111111 ;  
  7. struct Suf_auto {  
  8.     int tot , last , c[26][maxn<<1] , pre[maxn<<1] , val[maxn<<1] ;  
  9.     inline void new_node ( int step ) {  
  10.         int i ;  
  11.         val[++tot] = step ;  
  12.         for ( i = 0 ; i < 26 ; i ++ ) c[i][tot] = 0 ;  
  13.         pre[tot] = 0 ;  
  14.     }  
  15.     void build ( char *s , int len ) {  
  16.         int i , j , k ;  
  17.         tot = 0 ;  
  18.         new_node ( 0 ) ;  
  19.         last = 1 ;  
  20.         for ( i = 0 ; i < len ; i ++ ) {  
  21.             new_node ( val[last] + 1 ) ;  
  22.             int np = tot ;  
  23.             k = s[i] - 'a' ;  
  24.             while ( !c[k][last] && last ) c[k][last] = tot , last = pre[last] ;  
  25.             if ( !last ) pre[tot] = 1 ;  
  26.             else {  
  27.                 int q = c[k][last] ;  
  28.                 if ( val[q] != val[last] + 1 ) {  
  29.                     new_node ( val[last] + 1 ) ;  
  30.                     for ( j = 0 ; j < 26 ; j ++ ) c[j][tot] = c[j][q] ;  
  31.                     pre[tot] = pre[q] ;  
  32.                     pre[q] = pre[np] = tot ;  
  33.                     while ( c[k][last] == q && last )   
  34.                         c[k][last] = tot , last = pre[last] ;  
  35.                 }  
  36.                 else pre[tot] = q ;  
  37.             }  
  38.             last = np ;  
  39.         }  
  40.     }  
  41.     int dfs ( int rt , int step , int n ) {  
  42.         if ( step == n ) return val[rt] ;  
  43.         int i ;  
  44.         for ( i = 0 ; i < 26 ; i ++ )  
  45.             if ( c[i][rt] ) {  
  46.                 int k = dfs ( c[i][rt] , step + 1 , n ) ;  
  47.                 if ( k ) return k ;  
  48.             }  
  49.         return 0 ;  
  50.     }  
  51.     void solve ( int n ) {  
  52.         int i , j , k ;  
  53.         printf ( "%d\n" , dfs ( 1 , 0 , n ) - n + 1 ) ;  
  54.     }  
  55.     void travel ( int rt ) {  
  56.         int i ;  
  57.         printf ( "val[%d] = %d\n" , rt , val[rt] ) ;  
  58.         for ( i = 0 ; i < 26 ; i ++ )  
  59.             if ( c[i][rt] ) travel ( c[i][rt] ) ;  
  60.     }  
  61. } suf;  
  62.   
  63. char s[111111] ;  
  64. int main () {  
  65.     int cas , len , i , j ;  
  66.     scanf ( "%d" , &cas ) ;  
  67.     while ( cas -- ) {  
  68.         scanf ( "%s" , s ) ;  
  69.         len = strlen ( s ) ;  
  70.         int n = len ;  
  71.         for ( i = 0 ; i < n ; i ++ ) s[len++] = s[i] ;  
  72.         s[len] = 0 ;  
  73.         suf.build ( s , len ) ;  
  74.     //  suf.travel ( 1 ) ;  
  75.         suf.solve ( n ) ;  
  76.     }  
  77. }