• 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
    ",s[i]);
    87         for (int i = pos2+pos1+1; i > pos1; i--)
    88             printf("%d
    ",s[i]);
    89         for (int i = n-1; i > pos2+pos1+1; i--)
    90             printf("%d
    ", s[i]);
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    路径问题
    移动端推荐使用
    js获取各种宽高方法
    html 符号大全
    bzoj4923 K小值查询
    bzoj3781 小B的询问
    bzoj1799 [Ahoi2009]self 同类分布
    bzoj2005 [Noi2010]能量采集
    bzoj4039 集会
    bzoj2516 电梯
  • 原文地址:https://www.cnblogs.com/oneshot/p/4333978.html
Copyright © 2020-2023  润新知