[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 ...
随机推荐
- iphone开发笔记目录
http://www.cnblogs.com/syxchina/archive/2012/10/20/2732731.html#2653802
- Mybatis问题:There is no getter for property named 'unitId' in 'class java.lang.String'
Mybatis遇到的问题 问题: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.re ...
- 使用 IDEA和Maven 整合SSH框架
1.创建web工程 一路next 下去就行.完成后,IDEA会自动构建maven工程. 2.创建如下项目结构 需要将 java文件夹设置为SourcesRoot目录,否则无法创建package 设置操 ...
- PowerShell 异常处理
在使用 PowerShell 的过程中,发现它的异常处理并不像想象中的那么直观,所以在这里总结一下. Terminating Errors 通过 ThrowTerminatingError 触发的错误 ...
- PHP获取中英文字符串的首字母
使用场景:在对地区进行筛选时,我们经常会看到按照英文字母进行筛选定位,起初想着是数据表里存储上地区与首字母关联关系,但是觉得太麻烦,然后就想着根据地区名称来获取首字母,然后对地区进行分组,由此便用到了 ...
- JSTL与EL的区别
JSTL JSTL(JSP Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的.JSTL只能运行在支持J ...
- mysql中能够使用索引的典型场景
mysql 演示数据库:http://downloads.mysql.com/docs/sakila-db.zip 匹配全值 explain select * from rental where re ...
- Java进阶篇(六)——Swing程序设计(下)
三.布局管理器 Swing中,每个组件在容器中都有一个具体的位置和大小,在容器中摆放各自组件时很难判断其具体位置和大小,这里我们就要引入布局管理器了,它提供了基本的布局功能,可以有效的处理整个窗体的布 ...
- 怎么查看mysql的安装目录
如果忘记了MySQL的安装目录,怎么快速找到呢?方法或许很多,作者觉得这种最方便了 环境:windows+mysql+navicat 方法:进入mysql命令行输入:show variables li ...
- junit源码解析--核心类
JUnit 的概念及用途 JUnit 是由 Erich Gamma 和 Kent Beck 编写的一个开源的单元测试框架.它属于白盒测试,只要将待测类继承 TestCase 类,就可以利用 JUnit ...