[POJ3581]Sequence
[POJ3581]Sequence
题目大意:
给定序列\(A_{1\sim n}\),其中\(A_1\)为最大的数。要把这个序列分成\(3\)个非空段,并将每一段分别反转,求能得到的字典序最小的序列。
思路:
对于第一段,由于\(A_1\)是最大的数字,因此我们可以将\(A_{1\sim n}\)翻转,用后缀数组求最小后缀作为第一段。
对于剩下两段,如果仍然套用第一段的方法是行不通的。下面是反例:
9
8 4 -1 5 0 5 0 2 3
显然,该序列翻转后为3 2 0 5 0 5 -1 4 8
。最小后缀为-1 4 8
,作为第一段翻转后的值是最优的。
对于剩下两段,3 2 0 5 0 5
的最小后缀为0 5
,此时最终答案就变成了-1 4 8 0 5 3 2 0 5
,而我们不难发现最优解其实是-1 4 8 0 5 0 5 3 2
。
那么,问题出在哪里呢?
事实上,题目让我们求的是操作后整个序列字典序最小,因此我们在计算第二段是也需要考虑第三段的影响。我们不妨将去掉第一段后剩下的序列复制两遍接起来,求起点在前面一半的最小后缀。还是以上文的数据为例,将3 2 0 5 0 5
改成3 2 0 5 0 5 3 2 0 5 0 5
。此时我们求得最小后缀为0 5 0 5 3 2 0 5 0 5
。第二段为0 5 0 5
,第三段为3 2
。因此得到最后序列为-1 4 8 0 5 0 5 3 2
。
使用倍增+快排的后缀数组,时间复杂度是\(\mathcal O(n\log^2 n)\)的。
源代码:
#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
const int N=2e5;
int n,k,a[N],sa[N*2],rank[N*2],tmp[N*2],rev[N*2];
inline bool cmp(const int &i,const int &j) {
if(rank[i]!=rank[j]) return rank[i]<rank[j];
const int ri=i+k<n?rank[i+k]:-1;
const int rj=j+k<n?rank[j+k]:-1;
return ri<rj;
}
inline void suffix_sort(const int &nn) {
n=nn;
for(register int i=0;i<n;i++) {
sa[i]=i;
rank[i]=i<n?rev[i]:-1;
}
for(k=1;k<=n;k<<=1) {
std::sort(&sa[0],&sa[n],cmp);
tmp[sa[0]]=0;
for(register int i=1;i<n;i++) {
tmp[sa[i]]=tmp[sa[i-1]]+!!cmp(sa[i-1],sa[i]);
}
for(register int i=0;i<n;i++) {
rank[i]=tmp[i];
}
}
}
int main() {
const int n=getint();
for(register int i=0;i<n;i++) a[i]=getint();
std::reverse_copy(&a[0],&a[n],&rev[0]);
suffix_sort(n);
int p1=0,p2=0;
for(register int i=0;i<n&&(p1<1||n-p1<2);i++) {
p1=n-sa[i];
}
const int m=n-p1;
std::reverse_copy(&a[p1],&a[n],&rev[0]);
std::reverse_copy(&a[p1],&a[n],&rev[m]);
suffix_sort(m*2);
for(register int i=0;i<m*2&&(p2-p1<1||n-p2<1);i++) {
p2=n-sa[i];
}
std::reverse(&a[0],&a[p1]);
std::reverse(&a[p1],&a[p2]);
std::reverse(&a[p2],&a[n]);
for(register int i=0;i<n;i++) {
printf("%d\n",a[i]);
}
return 0;
}
[POJ3581]Sequence的更多相关文章
- POJ3581 Sequence —— 后缀数组
题目链接:https://vjudge.net/problem/POJ-3581 Sequence Time Limit: 5000MS Memory Limit: 65536K Total Su ...
- POJ3581:Sequence(后缀数组)
Description Given a sequence, {A1, A2, ..., An} which is guaranteed A1 > A2, ..., An, you are to ...
- POJ3581 Sequence(后缀数组)
题意:给一个串,串的第一个字符比后面的都大,要把它分成三段,然后反转每一段,求能得到的字典序最小的串是什么. 首先,第一段是可以确定的:把原串反转,因为第一个字符是最大的,它是唯一的,不存在反转串的后 ...
- 【后缀数组】poj3581 Sequence
考虑第一次切割,必然切割的是翻转后字典序最小的前缀,伪证: 若切割位置更靠前:则会导致第一个数翻转后更靠前,字典序必然更大. 若切割位置更靠后,则显然也会导致字典序更大. ↑,sa即可 对于第二次切割 ...
- POJ3581:Sequence——题解
http://poj.org/problem?id=3581 给一串数,将其分成三个区间并且颠倒这三个区间,使得新数列字典序最小. 参考:http://blog.csdn.net/libin56842 ...
- oracle SEQUENCE 创建, 修改,删除
oracle创建序列化: CREATE SEQUENCE seq_itv_collection INCREMENT BY 1 -- 每次加几个 STA ...
- Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等
功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...
- DG gap sequence修复一例
环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...
- Permutation Sequence
The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
随机推荐
- poj 1298 The Hardest Problem Ever
题目链接:http://poj.org/problem?id=1298 题目大意:按照所给的顺序要求将输入的字符串进行排列. #include <iostream> #include &l ...
- Python第三方库wordcloud(词云)快速入门与进阶
前言: 笔主开发环境:Python3+Windows 推荐初学者使用Anaconda来搭建Python环境,这样很方便而且能提高学习速度与效率. 简介: wordcloud是Python中的一个小巧的 ...
- TCP之listen&backlog
1. listen函数: #include <sys/socket.h> int listen(int sockfd, int backlog); ret-成功返回0 失败返回- list ...
- 打印 pmic register value
打印 PMIC register value 方式有二種, 一種是使用 adb shell cat pmic register 一種是直接在 code 裡 call dump pmic registe ...
- 64_m1
MAKEDEV-3.24-18.fc26.x86_64.rpm 13-Feb-2017 22:33 101030 MUMPS-5.0.2-8.fc26.i686.rpm 14-Feb-2017 13: ...
- javascript反混淆之packed混淆
function getKey() { var aaaafun = function(p, a, c, k, e, d) { e = function(c) { return (c < a ? ...
- 使用node.js做一个自用的天气插件
var request = require('request') var url = 'http://www.baidu.com/home/xman/data/superload' var cooki ...
- HDU-2389
Rain on your Parade Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 655350/165535 K (Java/Ot ...
- connect-falsh的用法
借鉴博客 http://yunkus.com/connect-flash-usage/
- linux下不解包查看tar包文件内容
为减少日志文件占用的空间,很多情况下我们会将日志文件以天或周为周期打包成tar.gz 包保存.虽然这样做有利空间充分利用,但当我们想查看压缩包内的内容时确很不方便.如果只是一个tar.gz文件,可以将 ...