The principle of the suffix array is simple, to make a string array of all suffixes of a string s, and to sort it, then each time it is determined that a string D is not a substring of s, only the time complexity of strlen (D) *log (strlen (s)) is required. Codevs1500 This problem is a naked question, test suffix array generation, if a one will be the suffix of s added to the suffix array and the time required to quickly sort the complexity of (n squared *log N), very low efficiency. The time complexity of generating a suffix array can generally be optimized to (N*log n*log N) using the multiplication method.
The idea of multiplication is a bit difficult to understand at first, just compare the first letter of each suffix, get a sequential list, and then compare the first two letters of each suffix with the order list that you got earlier, then compare the first 4 letters with the list of previous two letters. This is always compared to the previous (2^K) letters, when (2^K) >= The length of the original string can be stopped. Suppose we currently have a list of only the previous X-Letters, to compare the order of the first 2x letters of the 2 suffix, we only need to compare the first X-letters of the two suffixes of the order, if the same and then compare the two suffixes of the x+1 letter to the first 2x alphabetical order, because the string to compare the length of x, It is possible to use the previously obtained sequential list of only the first x letters of the suffix to achieve a quick comparison of the first 2x letters of the 2 suffixes, and the time complexity of the comparison is O (1).
Put a code:
1#include <iostream>2#include <cstdio>3#include <cstdlib>4#include <cstring>5#include <algorithm>6 #defineMAXN 160007 using namespacestd;8 CharS[MAXN];9 intn,order[2*MAXN];Ten structan_suffix{ One intSt,len; AFriendBOOL operator< (ConstAn_suffix A,ConstAn_suffix B) { - if(a.len==1)returns[a.st]<S[b.st]; - if(Order[a.st]!=order[b.st])returnorder[a.st]<Order[b.st]; the returnorder[a.st+ (a.len/2)]<order[b.st+ (b.len/2)]; - } -FriendBOOL operator== (ConstAn_suffix A,ConstAn_suffix B) { - if(a.len==1)returns[a.st]==S[b.st]; + return(Order[a.st]==order[b.st] && order[a.st+ (a.len/2)]==order[b.st+ (b.len/2)]); - } + }SUFF[MAXN]; A structan_order{ at intN,order; -FriendBOOL operator< (ConstAn_order A,ConstAn_order B) { - returna.order<B.order; - } - }ANS[MAXN]; - voidGet_order (intLen) { in intORDER2[MAXN]; - for(intI=0; i<n;i++) suff[i]=((an_suffix) {i,len}); toSort (suff,suff+n); + intt=1; order2[suff[0].st]=T; - for(intI=1; i<n;i++){ the if(! (suff[i-1]==suff[i]) t++; *order2[suff[i].st]=T; $ }Panax Notoginseng for(intI=0; i<n;i++) order[i]=Order2[i]; - } the intMain () { +scanf"%d",&n); Ascanf"%s", s); the intt=1; + while(1){ - Get_order (t); $ if(t>=n) Break; $t=t*2; - } - for(intI=0; i<n;i++) ans[i]=((An_order) {i,order[i]}); theSort (ans,ans+n); - for(intI=0; i<n;i++) printf ("%d\n", ans[i].n+1);Wuyi return 0; the}
Ans is used to record the order of each point, which is used to output the answer. The overloaded "<" in the data structure An_suffix is used to determine the order of the two suffixes under the current comparison length, and the overloaded "= =" Determines whether the two suffixes are equal under the current comparison length. Note that the order array must be open to 2*MAXN, because when the comparison length is (n-1), it is possible to access ORDER[ST+LEN/2] when the suffix operation begins with the last character, at which point the value should default to 0.
Suffix array-codevs1500