[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的更多相关文章

  1. POJ3581 Sequence —— 后缀数组

    题目链接:https://vjudge.net/problem/POJ-3581 Sequence Time Limit: 5000MS   Memory Limit: 65536K Total Su ...

  2. POJ3581:Sequence(后缀数组)

    Description Given a sequence, {A1, A2, ..., An} which is guaranteed A1 > A2, ..., An,  you are to ...

  3. POJ3581 Sequence(后缀数组)

    题意:给一个串,串的第一个字符比后面的都大,要把它分成三段,然后反转每一段,求能得到的字典序最小的串是什么. 首先,第一段是可以确定的:把原串反转,因为第一个字符是最大的,它是唯一的,不存在反转串的后 ...

  4. 【后缀数组】poj3581 Sequence

    考虑第一次切割,必然切割的是翻转后字典序最小的前缀,伪证: 若切割位置更靠前:则会导致第一个数翻转后更靠前,字典序必然更大. 若切割位置更靠后,则显然也会导致字典序更大. ↑,sa即可 对于第二次切割 ...

  5. POJ3581:Sequence——题解

    http://poj.org/problem?id=3581 给一串数,将其分成三个区间并且颠倒这三个区间,使得新数列字典序最小. 参考:http://blog.csdn.net/libin56842 ...

  6. oracle SEQUENCE 创建, 修改,删除

    oracle创建序列化: CREATE SEQUENCE seq_itv_collection            INCREMENT BY 1  -- 每次加几个              STA ...

  7. Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等

    功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...

  8. DG gap sequence修复一例

    环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...

  9. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

随机推荐

  1. js_数组去重效率对比

    学习javascript已经快两年了,也不知道到了什么程度了. 说说我对javascript的理解,在电脑的世界里,只有数据. 数组,对象,字符串.对这些数据进行操作就可以完成很多业务逻辑,和页面的交 ...

  2. hdu 3790 最短路径问题(双重权值,dijkstra算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 题目大意:题意明了,输出最短路径及其花费. 需要注意的几点:(1)当最短路径相同时,输出最小花费 ...

  3. vue-实现倒计时功能

    JavaScript 创建一个 countdown 方法,用于计算并在控制台打印距目标时间的日.时.分.秒数,每隔一秒递归执行一次. msec 是当前时间距目标时间的毫秒数,由时间戳相减得到,我们将以 ...

  4. centos_7.1.1503_src_4

    http://vault.centos.org/7.1.1503/os/Source/SPackages/ libkcompactdisc-4.10.5-3.el7.src.rpm 05-Jul-20 ...

  5. python3使用xlrd、xlwt、xlutils、openpyxl、xlsxwriter操作excel

    特色简介 xlrd主要用来读excel,针对.xls格式: xlwt主要用来写excel,针对.xls格式,超出excel 的单格内容长度上限32767,就会报错: xlutils结合xlrd可以达到 ...

  6. 【bzoj4518】征途

    懒得推式子了,总之是个斜率优化…… 先化一下题目要求的式子,再写一下dp方程,然后就是很自然的斜率优化了qwq #include<bits/stdc++.h> #define N 3005 ...

  7. Python简单的制作图片验证码

    -人人可以学Python--这里示范的验证码都是简单的,你也可以把字符扭曲 人人可以学Python.png Python第三方库无比强大,PIL 是python的一个d第三方图片处理模块,我们也可以使 ...

  8. [How to]如何自定义plist文件和读取plist文件内容

    1.简介 plist作为IOS的固化文件,就好比java中properties文件,但是在IOS中plist是可读写的. 本文将介绍自定义静态的plist文件. 2.自定义静态plist文件 右击你的 ...

  9. service XXX start启动报start: Rejected send message, 1 matche

    转,原文地址:http://blog.sina.com.cn/s/blog_56d8ea9001018w1l.html [问题]start: Rejected send messag现象:crifan ...

  10. hihocoder 1178 : 计数

    #1178 : 计数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Rowdark是一个邪恶的魔法师.在他阅读大巫术师Lich的传记时,他发现一类黑魔法来召唤远古生物, ...