[POJ 3581]Sequence
[POJ 3581]Sequence
标签: 后缀数组
题意
给你一串序列\(A_i\),保证对于$ \forall i \in [2,n],都有A_1 >A_i$。
现在需要把这个序列分成三段,并且将这三段分别翻转,求如何翻转使整个序列字典序最小。(每一段不能为空)
题解
首先可以确定第一段的位置。
注意到,\(A_1\)是最大的,所以我们就只用考虑怎样找到一个前缀使其翻转后的字典序最小。
(假如不是的话,就可能找到两个前缀翻转之后,一个为另一个的前缀,无法解决)
这等价于翻转之后找到一个后缀使其字典序最小,用后缀数组处理一下。
然后确定第二段的位置。
先翻转之后,找一个分割点使整个串最小。这等价于最小循环表示法问题。
可以直接用后缀数组解决,也有O(n)的做法。
Code
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
inline int read()
{
int sum=0,p=1;char ch=getchar();
while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
if(ch=='-')p=-1,ch=getchar();
while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
return sum*p;
}
const int maxn=4e5+20;
int n,a[maxn],sa[maxn],S[maxn],cnt;
void init()
{
n=read();
REP(i,0,n-1)a[i]=read(),S[cnt++]=a[i];
sort(S,S+cnt);
cnt=unique(S,S+cnt)-S;
REP(i,0,n-1)a[i]=lower_bound(S,S+cnt,a[i])-S;
}
int r[maxn*2];
int x[maxn],y[maxn]={0},bug[maxn]={0},v[maxn*2];
void suffix_array(int *r,int n)
{
int p=0,m=200000;
memset(v,-1,sizeof(v));
REP(i,0,m)bug[i]=0;
REP(i,0,n-1)bug[x[i]=r[i]]++;
REP(i,1,m)bug[i]+=bug[i-1];
DREP(i,n-1,0)sa[--bug[x[i]]]=i;
for(int j=1;p<n;j*=2,m=p)
{
p=0;REP(i,n-j,n-1)y[p++]=i;
REP(i,0,n-1)if(sa[i]>=j)y[p++]=sa[i]-j;
REP(i,0,m)bug[i]=0;
REP(i,0,n-1)bug[v[i]=x[y[i]]]++;
REP(i,1,m)bug[i]+=bug[i-1];
DREP(i,n-1,0)sa[--bug[v[i]]]=y[i];
REP(i,0,n-1)v[i]=x[i];p=1;x[sa[0]]=0;
REP(i,1,n-1)x[sa[i]]=v[sa[i-1]]==v[sa[i]] && v[sa[i-1]+j]==v[sa[i]+j] ?p-1:p++;
}
}
void doing()
{
REP(i,0,n-1)r[i]=a[n-i-1];
suffix_array(r,n);
int X=0;
REP(i,0,n-1)if(sa[i]>1){X=sa[i];break;}
REP(i,X,n-1)cout<<S[r[i]]<<endl;
//REP(i,0,n-X-1)x[i]=a[i+X+1];
n=X;
REP(i,n,2*n-1)r[i]=r[i-n];
suffix_array(r,2*n);
REP(i,0,2*n-1)if(sa[i]<n && sa[i]){X=sa[i];break;}
REP(i,X,n-1+X)cout<<S[r[i]]<<endl;
}
int main()
{
init();
doing();
return 0;
}
[POJ 3581]Sequence的更多相关文章
- POJ 3581 Sequence(后缀数组)
[题目链接] http://poj.org/problem?id=3581 [题目大意] 给出一个数列,将这个数列分成三段,每段分别翻转,使得其字典序最小,输出翻转后的数列. [题解] 首先,第一个翻 ...
- POJ 3581 Sequence [后缀数组]
Sequence Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6911 Accepted: 1543 Case Tim ...
- POJ 3581 Sequence(后缀数组)
Description Given a sequence, {A1, A2, ..., An} which is guaranteed A1 > A2, ..., An, you are to ...
- 后缀数组 POJ 3581 Sequence
题目链接 题意:把n个数字(A1比其他数字都大)的序列分成三段,每段分别反转,问字典序最小的序列. 分析:因为A1比其他数字都大,所以反转后第一段结尾是很大的数,相当是天然的分割线,第一段可以单独考虑 ...
- POJ 3581 Sequence ——后缀数组 最小表示法
[题目分析] 一见到题目,就有了一个显而易见obviously的想法.只需要每次找到倒过来最小的那一个字符串翻转就可以了. 然而事情并不是这样的,比如说505023这样一个字符串,如果翻转了成为320 ...
- POJ 3581 Sequence(后缀数组)题解
题意: 已知某字符串\(str\)满足\(str_1 > max\{str_2,str_3 \cdots str_n\}\),现要求把这个字符串分成连续的三组,然后每组都翻转,问字典序最小是什么 ...
- POJ 3581:Sequence(后缀数组)
题目链接 题意 给出n个数字的序列,现在让你分成三段,使得每一段翻转之后拼接起来的序列字典序最小.保证第一个数是序列中最大的数. 例如样例是{10, 1, 2, 3, 4},分成{1, 10}, {2 ...
- Sequence POJ - 3581 后缀数组
题意: 将一个序列分成非空的三部分,将每部分翻转后组合成一个新的序列, 输出这样操作得到的序列中字典序最小的序列 (保证第一个数是数组中最大的元素) 题解: 把数组当作串串. 因为第一个数最大,所以我 ...
- POJ 2442 Sequence
Pro. 1 给定k个有序表,取其中前n小的数字.组成一个新表,求该表? 算法: 由于 a1[1] < a1[2] < a1[3] ... <a1[n] a2[1] < a2 ...
随机推荐
- ASP.NET MVC5 中百度ueditor富文本编辑器的使用
随着网站信息发布内容越来越多,越来越重视美观,富文本编辑就是不可缺少的了,众多编辑器比较后我选了百度的ueditor富文本编辑器. 百度ueditor富文本编辑器分为两种一种是完全版的ueditor, ...
- fullpage.js的easing参数怎样配置自定义动画
首先看非官方文档 并没有详细的说明怎样去使用easing.js,所以我加的运动属性根本就不起作用, 再看,官方文档 Optionally, when using css3:false, you can ...
- SSE图像算法优化系列十五:YUV/XYZ和RGB空间相互转化的极速实现(此后老板不用再担心算法转到其他空间通道的耗时了)。
在颜色空间系列1: RGB和CIEXYZ颜色空间的转换及相关优化和颜色空间系列3: RGB和YUV颜色空间的转换及优化算法两篇文章中我们给出了两种不同的颜色空间的相互转换之间的快速算法的实现代码,但是 ...
- 验证插件——jquery.validate.js
下载地址:http://download.csdn.net/download/s592652578/9457421 教程:http://www.runoob.com/jquery/jquery-plu ...
- nodejs环境设置理解
本小白今天忙了一下午,就为了设置好nodejs的环境变量. 其实理解了nodejs调用的过程就会发现环境变量的设置及其简单(当然,我是边安装边想的,不知我想的对不对) 首先,npm下载的模块分为全局模 ...
- Go语言学习索引
<Go并发编程实战>示例项目 项目地址: https://github.com/hyper-carrot/goc2p 项目安装: 用git clone获取项目,并将其根目录作为一个工作区. ...
- Sql Server的艺术(二) SQL复杂条件搜索
本次讲到where字句中经常用到的集中较为复杂的搜索条件,包括组合的查询条件.IN运算符.NOT运算符.LIKE运算符和相关通配符. 学习本节需要用到一下两张表: CREATE TABLE TEACH ...
- C语言预处理 编译 汇编 链接四个阶段
c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接. 编译过程 编译过程又可以分成两个阶段:编译和会汇编. 编译 编译是读取源程序(字符流),对之进行词法和语法的分析,将高 ...
- [Nginx]单机环境的多应用配置
# 服务层 # https://github.com/farwish/alconservice # alconservice.conf server { listen 8090; root /home ...
- 浅析调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException
废话不多说,直接进入正题:如何使用JSR303的validate,进行数据校验,失败后直接抛出异常加入流转信息中,并在form页面提示出来. 首先我们为了启用验证,需要向 项目中添加Bean验证的实现 ...