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 }
时间: 2024-10-12 05:59:43

POJ3581---Sequence 后缀树组的相关文章

[whu1564]后缀树组

http://acm.whu.edu.cn/land/problem/detail?problem_id=1564 思路:先把串复制一遍,在末尾补个标记,后缀树组跑一下,扫一遍就ok了(过滤后缀在后半部分的). 1 #pragma comment(linker, "/STACK:10240000,10240000") 2 3 #include <iostream> 4 #include <cstdio> 5 #include <algorithm>

ural1297(后缀树组+rmq)

Palindrome 题意: 求给定字符串的最长回文子串. 分析: 首先想到的是求str与反序的str的最大公共子串,考虑abcdba这种情况,所以对于求出的公共子串判断一下是否是回文串即可.还有一种做法是枚举每一个字符为回文串的中间点,求出这个字符的后缀与前缀的最长公共子串就是回文串.对于前缀可以认为是反序str中对应字符的后缀,根据后缀树组中height数组的性质,suffix(i)和suffix(j)的最长公共前缀为height[rank[i]+1],height[rank[i]+2]--

K-th occurrence(后缀树组+划分树+ST表+RMQ+二分)

2019CCPC网络选拔赛1003 HDU6704 题目大意: T个测试样例.一个长度为N的字符串S,之后Q个[l,r,k],表示一个子串S[l,r],求出第k个该子串的下标.起始坐标为1.不存在输出-1. 数据范围:1≤T≤20,  1≤N≤105,  1≤Q≤105,  1≤l≤r≤N,  1≤k≤N,  |S|=N; 赛后补题.参考题解说后缀树组+划分树+ST表+二分. 比赛的时候只会后缀树组不会划分树,赛后仔细想,觉得后缀数组可以,然而并不,会TLE. 补提的时候先是采用后缀树组+划分树

POJ3581:Sequence(后缀数组)

Description 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 or

后缀树组(SA)初探

还没有什么任意两个后缀的LCP这些玩意儿. 启蒙题:输入一个串S,求最长的串T使得T在S中出现过不止一次.输出T的长度. 1 #include <algorithm> 2 #include <stdio.h> 3 #include <string.h> 4 #define N 100 5 char s[N+1]; 6 int n, sa[N], rank[N], height[N]; 7 namespace SABuilder { 8 int cnt[N], t1[N&

HDU4436---str2int 后缀树组(12年天津区域赛)

str2int Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1568    Accepted Submission(s): 540 Problem Description In this problem, you are given several strings that contain only digits from '0'

hdu 4893 (多校1007)Wow! Such Sequence!(线段树&amp;二分&amp;思维)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 352    Accepted Submission(s): 104 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

[转载]字典树(trie树)、后缀树

(1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串.和普通树不同的地方是,相同的字符串前缀共享同一条分支.还是例子最清楚.给出一组单词,inn, int, at, age, adv, ant, 我们可以得到下面的Trie: 可以看出: 每条边对应一个字母. 每个节点对应一项前

跳跃表,字典树(单词查找树,Trie树),后缀树,KMP算法,AC 自动机相关算法原理详细汇总

第一部分:跳跃表 本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈"跳跃表"的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢. 跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类