POJ3581---Sequence 后缀树组

题意: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 }

 

你可能感兴趣的:(sequence)