POJ 3581 Sequence [后缀数组]
| Time Limit: 5000MS | Memory Limit: 65536K | |
| Total Submissions: 6911 | Accepted: 1543 | |
| Case Time Limit: 2000MS | ||
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 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
Source
题意:
给出一个字符串,要求将其切成3段,然后将每段翻转,使得得到的新串字典序最小
保证原串第一个字符的字典序比后面的都大
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=2e5+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,m,c[N],t1[N],t2[N];
int s[N],mp[N];
void iniMP(){
sort(mp+,mp++n);
int p=;mp[++p]=mp[];
for(int i=;i<=n;i++) if(mp[i]!=mp[i-]) mp[++p]=mp[i];
mp[]=p;
}
int Bin(int v){
int l=,r=mp[];
while(l<=r){
int mid=(l+r)>>;
if(v==mp[mid]) return mid;
else if(v<mp[mid]) r=mid-;
else l=mid+;
}
return ;
} int sa[N],rnk[N],height[N];
inline bool cmp(int *r,int a,int b,int j){
return a+j<=n&&b+j<=n&&r[a]==r[b]&&r[a+j]==r[b+j];
}
void getSA(int s[]){
m=mp[];
int *r=t1,*k=t2;
for(int i=;i<=m;i++) c[i]=;
for(int i=;i<=n;i++) c[r[i]=s[i]]++;
for(int i=;i<=m;i++) c[i]+=c[i-];
for(int i=n;i>=;i--) sa[c[r[i]]--]=i; for(int j=;j<=n;j<<=){
int p=;
for(int i=n-j+;i<=n;i++) k[++p]=i;
for(int i=;i<=n;i++) if(sa[i]>j) k[++p]=sa[i]-j; for(int i=;i<=m;i++) c[i]=;
for(int i=;i<=n;i++) c[r[k[i]]]++;
for(int i=;i<=m;i++) c[i]+=c[i-];
for(int i=n;i>=;i--) sa[c[r[k[i]]]--]=k[i]; swap(r,k);p=;r[sa[]]=++p;
for(int i=;i<=n;i++) r[sa[i]]=cmp(k,sa[i],sa[i-],j)?p:++p;
if(p>=n) break;m=p;
}
} void solve(){
reverse(s+,s++n);
getSA(s);
int p=;
while(sa[p]<=) p++;
for(int i=sa[p];i<=n;i++) printf("%d\n",mp[s[i]]); n=sa[p]-;
for(int i=;i<=n;i++) s[i+n]=s[i];
n<<=;
getSA(s);
p=;
n>>=;
while(sa[p]==||sa[p]>n) p++;
for(int i=sa[p];i<=n;i++) printf("%d\n",mp[s[i]]);
for(int i=;i<sa[p];i++) printf("%d\n",mp[s[i]]);
} int main(){
freopen("in","r",stdin);
n=read();
for(int i=;i<=n;i++) s[i]=mp[i]=read();
iniMP();
for(int i=;i<=n;i++) s[i]=Bin(s[i]);
solve();
}
POJ 3581 Sequence [后缀数组]的更多相关文章
- POJ 3581 Sequence(后缀数组)
Description Given a sequence, {A1, A2, ..., An} which is guaranteed A1 > A2, ..., An, you are to ...
- POJ 3581 Sequence ——后缀数组 最小表示法
[题目分析] 一见到题目,就有了一个显而易见obviously的想法.只需要每次找到倒过来最小的那一个字符串翻转就可以了. 然而事情并不是这样的,比如说505023这样一个字符串,如果翻转了成为320 ...
- [POJ 3581]Sequence
[POJ 3581]Sequence 标签: 后缀数组 题目链接 题意 给你一串序列\(A_i\),保证对于$ \forall i \in [2,n],都有A_1 >A_i$. 现在需要把这个序 ...
- 后缀数组 POJ 3581 Sequence
题目链接 题意:把n个数字(A1比其他数字都大)的序列分成三段,每段分别反转,问字典序最小的序列. 分析:因为A1比其他数字都大,所以反转后第一段结尾是很大的数,相当是天然的分割线,第一段可以单独考虑 ...
- POJ 3581 Sequence(后缀数组)题解
题意: 已知某字符串\(str\)满足\(str_1 > max\{str_2,str_3 \cdots str_n\}\),现要求把这个字符串分成连续的三组,然后每组都翻转,问字典序最小是什么 ...
- POJ3581 Sequence —— 后缀数组
题目链接:https://vjudge.net/problem/POJ-3581 Sequence Time Limit: 5000MS Memory Limit: 65536K Total Su ...
- POJ 2406 KMP/后缀数组
题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就 ...
- POJ 1743-POJ - 3261~后缀数组关于最长字串问题
POJ 1743 题意: 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1~~88范围内的整数,现在要找一个重复的主题.“主题”是整个音符序列的一个子串,它需 ...
- POJ - 1226 Substrings (后缀数组)
传送门:POJ - 1226 这个题跟POJ - 3294 和POJ - 3450 都是一样的思路,一种题型. POJ - 3294的题解可以见:https://www.cnblogs.com/li ...
随机推荐
- QT 操作 excel 教程
前言:环境 win7 64位,QT4.8.5,QT Creator 在 .pro 文件中加入语句"CONFIG+=qaxcontainer"; 源码如下: //main.cpp # ...
- block的修饰词为什么选用copy
想必很多开发人员知道一般用copy修饰block,接下来就讲解为什么需要用copy,甚至会讲到其实用strong修饰block也是可以的 在 Objective-C 语言中,一共有 3 种类型的 bl ...
- 算法-java代码实现选择排序
选择排序
- 邓_php面试【003】——完整版
php面试题汇总四(基础篇附答案) 1. 什么事面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰.主要特征:封装.继承.多态. 2. SESSION ...
- Vuejs技术栈知识点小结
前言 上家公司的项目主要是使用jQuery和Angular1,然后自己学了React,没想到来到这家公司突然开始做vue,不过vue还是挺容易上手的.下面是vue技术栈的一些总结,都是来自官网,主要是 ...
- Algorithms code
一些值得回看的小算法. 最长的连续子数组 子数组数字不重复 int [] arr={1,2,3,4,7}; //输出4 int [] arr1={1,2,3,4,1,2,3,4,5,1}; //输出5 ...
- -------- ROOTKIT 核心技术——系统服务调度表挂钩调试(PART III) --------
---------------------------------------------------------------------------------------- 本篇开始进行真枪实弹的 ...
- jQuery时间格式插件-moment.js的使用
jQuery时间格式插件-moment.js的使用 moment.js插件的使用,使用之前在页面引入对应的js文件: 详细的操作可见moment中文官网:http://momentjs.cn/ 日期格 ...
- 寄存器(CPU原理)
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 洛谷P1233 [木棍加工]
主要思路: 这道题一眼看过去就可以贪心.. 首先可以按L排序.. 显然排序之后我们就可以抛开L不管了.. 然后就可以愉快的贪心了.. 细节: 这道题可以看成用 最少的合法序列(详见原题) 装下所有木棍 ...