【解题思路】
将原串复制一份拼接到原串后作为处理串,可以对处理串的前一半后缀排序,即可得出顺序。复杂度O(Llog2L)。
【参考代码】
也是naive的时候写的。。后缀数组居然是用桶排求的。。
1 #pragma optimize(2) 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #define REP(I,start,end) for(int I=(start);I<=(end);I++) 6 #define PER(I,start,end) for(int I=(start);I>=(end);I--) 7 using namespace std; 8 typedef vector<int> vecint; 9 vecint srt[100010]; 10 int suffix[100010],rank[100010],srnk[100010]; 11 char st[100010]; 12 int main() 13 { 14 scanf("%s",st); 15 int n=strlen(st); 16 memset(srt,0,sizeof(srt)); 17 REP(i,1,n) 18 srt[st[i-1]].push_back(i); 19 int cnt=0,tot=0; 20 REP(i,0,255) 21 if(!srt[i].empty()) 22 { 23 cnt++; 24 for(vecint::iterator it=srt[i].begin();it!=srt[i].end();it++) 25 { 26 int now=*it; 27 suffix[++tot]=now; 28 rank[now]=cnt; 29 } 30 } 31 for(int i=1;i<n;i<<=1) 32 { 33 memset(srt,0,sizeof(srt)); 34 REP(j,1,n) 35 { 36 int now=i+j; 37 now-=(now>n)*n; 38 srt[rank[now]].push_back(j); 39 } 40 tot=cnt=0; 41 REP(j,0,n) 42 if(!srt[j].empty()) 43 { 44 cnt++; 45 for(vecint::iterator it=srt[j].begin();it!=srt[j].end();it++) 46 { 47 int now=*it; 48 suffix[++tot]=now; 49 srnk[now]=cnt; 50 } 51 } 52 memset(srt,0,sizeof(srt)); 53 REP(j,1,n) 54 srt[rank[suffix[j]]].push_back(suffix[j]); 55 cnt=tot=0; 56 REP(j,0,n) 57 if(!srt[j].empty()) 58 { 59 int last=-1; 60 for(vecint::iterator it=srt[j].begin();it!=srt[j].end();it++) 61 { 62 int now=*it,pnt=srnk[now]; 63 cnt+=pnt>last; 64 last=pnt; 65 suffix[++tot]=now; 66 rank[now]=cnt; 67 } 68 } 69 } 70 REP(i,1,n) 71 putchar(st[(suffix[i]+n-2)%n]); 72 putchar(‘\n‘); 73 return 0; 74 }
时间: 2024-11-08 19:23:30