Sequence POJ - 3581 (后缀数组)
Posted iwannabe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sequence POJ - 3581 (后缀数组)相关的知识,希望对你有一定的参考价值。
Given a sequence, {A1, A2, ..., An} which is guaranteed A1 > A2, ..., An, you are to cut it into three sub-sequences and reverse them separately to form a new one which is the smallest possible sequence in alphabet order.
The alphabet order is defined as follows: for two sequence {A1, A2, ..., An} and {B1, B2, ..., Bn}, we say {A1, A2, ..., An} is smaller than {B1, B2, ..., Bn} if and only if there exists such i ( 1 ≤ i ≤ n) so that we have Ai < Bi and Aj = Bj for each j < i.
Input
The first line contains n. (n ≤ 200000)
The following n lines contain the sequence.
Output
output n lines which is the smallest possible sequence obtained.
Sample Input
5 10 1 2 3 4
Sample Output
1 10 2 4 3
Hint
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<vector> 6 #include<algorithm> 7 using namespace std; 8 9 const int maxn = 4e5+10; 10 int s[maxn]; 11 int ss[maxn]; 12 int sa[maxn],t[maxn],t2[maxn],c[maxn]; 13 14 void build_sa(int n,int m) 15 { 16 int i,*x=t,*y=t2; 17 for(i=0; i<m; i++)c[i]=0; 18 for(i=0; i<n; i++)c[x[i]=s[i]]++; 19 for(i=1; i<m; i++)c[i]+=c[i-1]; 20 for(i=n-1; i>=0; i--)sa[--c[x[i]]]=i; 21 for(int k=1; k<=n; k<<=1) 22 { 23 int p=0; 24 for(i=n-k; i<n; i++)y[p++]=i; 25 for(i=0; i<n; i++)if(sa[i] >= k)y[p++]=sa[i]-k; 26 for(i=0; i<m; i++)c[i] = 0; 27 for(i=0; i<n; i++)c[x[y[i]]]++; 28 for(i=1; i<m; i++)c[i]+=c[i-1]; 29 for(i=n-1; i>=0; i--)sa[--c[x[y[i]]]] = y[i]; 30 swap(x,y); 31 p=1,x[sa[0]]=0; 32 for(i=1; i<n; i++) 33 x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]?p-1:p++; 34 if(p>=n)break; 35 m=p; 36 } 37 } 38 39 int ht[maxn],rk[maxn]; 40 41 void getHeight(int n) 42 { 43 int i,j,k=0; 44 for(i=1; i<=n; i++)rk[sa[i]] = i; 45 for(i=0; i<n; i++) 46 { 47 if(k)k--; 48 int j = sa[rk[i]-1]; 49 while(s[i+k] == s[j+k] && s[i+k] != ‘$‘)k++; 50 ht[rk[i]] = k; 51 } 52 } 53 int n; 54 vector<int>v; 55 56 int cmp(int *s,int pos1,int pos2,int len) 57 { 58 for(int i=0; i<len; i++) 59 { 60 if(s[pos1+i] < s[pos2+i])return -1; 61 if(s[pos1+i] > s[pos2+i])return 1; 62 } 63 return 0; 64 } 65 66 int main() 67 { 68 scanf("%d",&n); 69 v.clear(); 70 for(int i=0; i<n; i++)scanf("%d",&ss[i]),v.push_back(ss[i]); 71 reverse(ss,ss+n); 72 sort(v.begin(),v.end()); 73 v.erase(unique(v.begin(),v.end()),v.end()); 74 for(int i=0; i<n; i++)s[i] = lower_bound(v.begin(),v.end(),ss[i])-v.begin()+1; 75 s[n] = 0; 76 build_sa(n+1,maxn); 77 getHeight(n); 78 int pos1 = 0; 79 int pos2 = 0; 80 for(int i=1; i<=n; i++) 81 { 82 if(sa[i] > 1) 83 { 84 pos1 = sa[i]; 85 break; 86 } 87 } 88 for(int i=0; i<pos1; i++)s[pos1+i] = s[i]; 89 int fn = 2*pos1; 90 s[fn] = 0; 91 // cout << pos1 << endl; 92 build_sa(fn+1,maxn); 93 getHeight(fn); 94 for(int i=1; i<=fn; i++) 95 { 96 if(sa[i] > 0 && sa[i] < pos1) 97 { 98 pos2 = sa[i]; 99 break; 100 } 101 } 102 for(int i=pos1; i<n; i++)printf("%d ",ss[i]); 103 for(int i=pos2; i<pos1; i++)printf("%d ",ss[i]); 104 for(int i=0; i<pos2; i++)printf("%d ",ss[i]); 105 } 106 107 /* 108 9 109 9 -2 8 1 1 8 1 1 1 110 111 9 112 9 -2 8 1 1 8 1 1 2 113 */
以上是关于Sequence POJ - 3581 (后缀数组)的主要内容,如果未能解决你的问题,请参考以下文章