码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3581---Sequence 后缀树组

时间:2015-03-13 00:02:34      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

题意:n个数字组成的序列,第一个数字最大,,把序列分成3部分,每个部分分别翻转,输出翻转后字典序最小的序列。。

 

后缀数组变一下,,先求出 第一个分割的位置,,然后再求一次后缀数组,,求出第二个位置。。输出就好了。

此题要采用单组输入。。。

 1 #include <set>
 2 #include <map>
 3 #include <cmath>
 4 #include <ctime>
 5 #include <queue>
 6 #include <stack>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 typedef unsigned long long ull;
16 typedef long long ll;
17 const int inf = 0x3f3f3f3f;
18 const double eps = 1e-8;
19 const int maxn = 2e5+10;
20 int s[maxn], rev_s[maxn << 1];
21 int sa[maxn], rank[maxn], tmp[maxn];
22 int k, sort_len;
23 bool cmp(int i, int j)
24 {
25     if (rank[i] != rank[j])
26         return rank[i] < rank[j];
27     else
28     {
29         int x = i + k <= sort_len ? rank[i+k] : -1;
30         int y = j + k <= sort_len ? rank[j+k] : -1;
31         return x < y;
32     }
33 }
34 void build_sa(int str[], int len)
35 {
36     sort_len = len;
37     for (int i = 0; i <= len; i++)
38     {
39         sa[i] = i;
40         rank[i] = i < len ? str[i] : -1;
41     }
42     for (k = 1; k <= len; k *= 2)
43     {
44         sort(sa, sa + len + 1, cmp);
45         tmp[sa[0]] = 0;
46         for (int i = 1; i <= len; i++)
47         {
48             tmp[sa[i]] = tmp[sa[i-1]] + (cmp(sa[i-1],sa[i]) ? 1 : 0);
49         }
50         for (int i = 0; i <= len; i++)
51             rank[i] = tmp[i];
52     }
53 }
54 int main(void)
55 {
56     #ifndef ONLINE_JUDGE
57         freopen("in.txt","r",stdin);
58     #endif
59     int n;
60     //while (~scanf ("%d", &n))
61     scanf ("%d", &n);
62     {
63         for (int i = 0; i < n; i++)
64             scanf ("%d", s + i);
65         reverse_copy(s, s + n, rev_s);
66         build_sa(rev_s, n);
67         int pos1;
68         for (int i = 0; i <= n; i++)
69         {
70             pos1 = n - sa[i] - 1;
71             if (pos1 >= 0 && pos1 <= n - 3)
72                 break;
73         }
74         int len = n - pos1 - 1;
75         reverse_copy(s+pos1+1, s+n, rev_s);
76         reverse_copy(s+pos1+1, s+n, rev_s+len);
77         build_sa(rev_s, len << 1);
78         int pos2;
79         for (int i = 0; i <= 2 * len; i++)
80         {
81             pos2 = len - sa[i] - 1;
82             if (sa[i] < len  && pos1+1+pos2 < n-1)
83                 break;
84         }
85         for (int i = pos1; i >= 0; i--)
86             printf("%d\n",s[i]);
87         for (int i = pos2+pos1+1; i > pos1; i--)
88             printf("%d\n",s[i]);
89         for (int i = n-1; i > pos2+pos1+1; i--)
90             printf("%d\n", s[i]);
91     }
92     return 0;
93 }

 

POJ3581---Sequence 后缀树组

标签:

原文地址:http://www.cnblogs.com/oneshot/p/4333978.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!