Give a string, the string is the first to connect, want our output from where to start, go clockwise, or you walk the clock, the dictionary is the largest
If there are multiple strings with the largest dictionary order, the smaller the starting subscript the better, and if the starting subscript is the same, the clockwise priority.
The original string is Abab, then as long as the original string is appended, into the abababab#, #是一个很小的字符, and then the suffix array, sa[n-1] is the best dictionary order of the subscript, n is the length of the abababab#
Counterclockwise, as long as the string upside down, [email protected],@ is a very large character, and then a suffix array, then as long as the traversal rank[0,m), find the largest rank of the corresponding subscript is counterclockwise dictionary order the largest subscript.
1 #pragmaWarning (disable:4996)2#include <stdio.h>3#include <string.h>4#include <math.h>5#include <vector>6#include <queue>7#include <stack>8#include <map>9#include <Set>Ten#include <algorithm> One#include <iostream> A#include <functional> -#include <string> - Const intINF =1<< -; the Const DoubleEPS = 1e-5; -typedefLong LongLL; - /* - + */ - Const intN =40000+Ten; + intRank[n], r[n], height[n], c[n], bucket[n], sa[n], tmp[n]; A //[0,n] The length of the string, the size of the [0,m] Character Set at voidBUILDSA (intNintm) - { - int*x = rank, *y = tmp, *T, K, p; - for(inti =0; i<m; ++i) C[i] =0; - for(inti =0; i<n; ++i) C[x[i] = r[i]]++; - for(inti =1; i<m; ++i) C[i] + = c[i-1]; in for(inti = n-1; I >=0; -i) sa[--c[x[i]] =i; - to for(k =1; K <= N; K <<=1) + { -p =0; the for(inti = n-k; i<n; ++i) y[p++] =i; * for(inti =0; i<n; ++i)if(Sa[i] >= k) y[p++] = Sa[i]-K; $ Panax Notoginseng for(inti =0; i<n; ++i) Bucket[i] = X[y[i];//the size of the first keyword is collected by rank, Y[i] is subscript, so the y[i] as the subscript is good to understand more - for(inti =0; i<m; ++i) C[i] =0; the for(inti =0; i<n; ++i) c[bucket[i]]++; + for(inti =1; i<m; ++i) C[i] + = c[i-1]; A for(inti = n-1; I >=0; -i) sa[--c[bucket[i]] =Y[i]; the +t = x, x = y, y =T; -p =1; x[sa[0]] =0; $ for(inti =1; i<n; ++i) $X[sa[i]] = y[sa[i-1] [= Y[sa[i]] && y[sa[i-1] + K] = = Y[sa[i] + K]? P-1: p++; - if(P >= N) Break; -m =p; the } - }Wuyi the //H[i] = Height[rank[i]] h[i] >= h[i-1]-1; - //[0,n] Wu voidMakeheight (intN) - { About intI, j, k =0; $ for(i =0; I <= N; ++i) Rank[sa[i] =i; - //the nth character ranking is 0,sa[rank[i]-1] out of bounds, so don't count - for(i =0; i<n; height[rank[i++]] =k) - for(K. k--:0, j = Sa[rank[i]-1]; R[i + K] = = R[j + K]; k++); A } + the CharStr[n]; -STD::stringAns1,ans2; $ intidx1,idx2; the intMain () the { the intt,n,m; thescanf"%d",&t); - while(t--) in { theans1 = Ans2 =""; thescanf"%d",&n); Aboutscanf"%s", str); the for(intI=0; i<n;++i) theR[i] = str[i]-'a'+1; them =N; + for(intI=0; i<n;++i) -r[m++] = str[i]-'a'+1; ther[m++] =0;BayiBUILDSA (M, -); theIDX1 = sa[m-1]; the //printf ("%d\n", Sa[m-1]); -m =N; - for(inti=idx1; m--;++i) theAns1 + = R[i] +'a'-1; them =0; the for(inti=n-1; i>=0; --i) ther[m++] = str[i]-'a'; - for(inti=n-1; i>=0; --i) ther[m++] = str[i]-'a'; ther[m++] = -; theBUILDSA (M, -);94 intMa = rank[0]; theIDX2 =0; the for(intI=1; i<n;++i) the {98 if(Rank[i] >=Ma) About { -Ma =Rank[i];101IDX2 =i;102 }103 }104m =N; the for(inti=idx2;m--;++i)106Ans2 + = R[i] +'a';107IDX1 + +;108IDX2 = N-idx2;109 if(Ans1 >ans2) the {111printf"%d%d\n", Idx1,0); the }113 Else if(Ans1 <ans2) the { theprintf"%d%d\n", IDX2,1); the }117 Else118 {119 if(idx1<=idx2) -printf"%d%d\n", Idx1,0);121 Else122printf"%d%d\n", IDX2,1);123 }124 } the return 0;126}
2015 Changchun Online Tournament 1006 (suffix array or minimum notation)