POJ1509 Glass Beads (后缀自动机)
题意:一个字符串可以将第一个字符放到最后一位,然后问不断这样做可以得到的字典序最小的字符串
1 #include <stdio.h> 2 #include <string.h> 3 #include <set> 4 #include <algorithm> 5 using namespace std ; 6 7 typedef long long LL ; 8 typedef unsigned long long ULL ; 9 typedef pair < int , int > pii ; 10 11 #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) 12 #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) 13 #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) 14 #define clr( a , x ) memset ( a , x , sizeof a ) 15 16 const int MAXN = 40005 ; 17 const int W = 26 ; 18 19 struct Node { 20 Node* next[W] ; 21 Node* fail ; 22 int len ; 23 int l ; 24 void newnode () { 25 clr ( next , 0 ) ; 26 fail = NULL ; 27 len = l = 0 ; 28 } 29 } ; 30 31 typedef Node* P_Node ; 32 33 struct SAM { 34 Node node[MAXN] ; 35 P_Node last , root ; 36 int cnt ; 37 38 void init () { 39 cnt = 0 ; 40 node->newnode () ; 41 root = last = node ; 42 } 43 44 void add ( int c ) { 45 P_Node p = last , np = node + ( ++ cnt ) ; 46 np->newnode () ; 47 np->l = np->len = p->len + 1 ; 48 last = np ; 49 for ( ; p && !p->next[c] ; p = p->fail ) p->next[c] = np ; 50 if ( !p ) np->fail = root ; 51 else { 52 if ( p->len + 1 == p->next[c]->len ) np->fail = p->next[c] ; 53 else { 54 P_Node q = p->next[c] , nq = node + ( ++ cnt ) ; 55 *nq = *q ; 56 nq->len = p->len + 1 ; 57 nq->l = np->len ; 58 q->fail = np->fail = nq ; 59 for ( ; p && p->next[c] == q ; p = p->fail ) p->next[c] = nq ; 60 } 61 } 62 } 63 } ; 64 65 SAM sam ; 66 char s[MAXN] ; 67 int n ; 68 69 void solve () { 70 sam.init () ; 71 scanf ( "%s" , s ) ; 72 n = strlen ( s ) ; 73 rep ( i , 0 , n ) sam.add ( s[i] - 'a' ) ; 74 rep ( i , 0 , n ) sam.add ( s[i] - 'a' ) ; 75 P_Node now = sam.root ; 76 rep ( i , 0 , n ) { 77 rep ( j , 0 , W ) if ( now->next[j] ) { 78 now = now->next[j] ; 79 break ; 80 } 81 } 82 printf ( "%d\n" , now->l - n + 1 ) ; 83 } 84 85 int main () { 86 int T ; 87 scanf ( "%d" , &T ) ; 88 For ( i , 1 , T ) solve () ; 89 return 0 ; 90 }