[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. JDBC+Servlet+JSP实现基本的增删改查(简易通讯录)

    前言: 最近学习JavaWeb的过程中,自己实践练手了几个小项目,目前已经上传到我的Github上https://github.com/Snailclimb/JavaWebProject.目前只上传了 ...

  2. Mojo_1_第一个简单例子

    use Mojolicious::Lite; #根目录,Get方法打开 #正接显示文本text get '/' => sub{ my $service = shift; $service-> ...

  3. face_recognition 人脸识别报错

    [root@localhost examples]# python facerec_from_video_file.py RuntimeError: module compiled against A ...

  4. appium===使用weditor代替ui automator viewer

    weditor 一个元素定位工具,并可实现通过wifi连接移动端进行定位. https://github.com/openatx/uiautomator2 python安装方式: pip instal ...

  5. 在linux内核中获得比jiffies精度更高的时间值【转】

    转自:http://blog.chinaunix.net/uid-20672257-id-2831219.html 内核一般通过jiffies值来获取当前时间.尽管该数值表示的是自上次系统启动到当前的 ...

  6. 【常见的SQL Server连接失败错误以及解决方法】

    [常见的SQL Server连接失败错误以及解决方法] http://blog.csdn.net/feixianxxx/article/details/5523922 ADO连接SQL Server ...

  7. git - 开发者电脑与服务器的配置

    首先公司要有一台git服务器,现在一般都托管在github服务器上,在中国可能会托管到oschina上,oschina有一点好处就是可以免费托管私有项目,而在github上想要托管自己的项目是收费的, ...

  8. C基础 时间业务实战代码

    引言 业务代码中遇到这样需求, 1. 二者是同一天吗, 2. 时间戳和时间串来回转, 3. 其它扩展需求 等. C写代码同样需要处理这方面时间问题. 本文就是为了解决这个问题. 相比其它时间库, 这里 ...

  9. nginx配置文件的详细讲解

    user nginx nginx; #定义Nginx运行的用户和用户组worker_processes 1; #nginx进程数,建议设置为等于CPU总核心数worker_rlimit_nofile ...

  10. iframe自适应高度的方法

    不带边框的iframe因为能和网页无缝的结合从而不刷新新页面的情况下实现更新页面部分的数据成为可能,可是iframe却不像层那样可以收缩自如,iframe高度需要动态的调整需要JS来配合使用,只能通过 ...