http://poj.org/problem?id=3581

给一串数,将其分成三个区间并且颠倒这三个区间,使得新数列字典序最小。

参考:http://blog.csdn.net/libin56842/article/details/46417301

(不是论文题,但是还是借鉴了题解,我是真的菜)

首先我们分成的三个区间肯定是一个前缀+中间一段+一个后缀。

那么我们先求前缀,方法很简单,只需要将原数列倒着存,然后找字典序最小的后缀即可。可以用后缀数组实现。

(因为原数列前缀的颠倒肯定是原数列颠倒后的其中一个后缀)

再考虑如何求中间一段。我们先把前面求完的部分扣掉,然后求字典序最小的后缀……?

并不是这样,比如3 5 0 5 0 5,按照这个方法我们得到的是0 5,但实际上我们要得到0 5 0 5。

所以为了避免这种情况,我们将这个数列倍长,这样就能使得0505小于05了。

最后再把剩下的一点输出即可。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
const int N=4e5+;
int n,m,t,rank[N],sa[N],height[N],w[N],b[N],s[N];
inline bool pan(int *x,int i,int j,int k){
int ti=i+k<n?x[i+k]:-;
int tj=j+k<n?x[j+k]:-;
return x[i]==x[j]&&ti==tj;
}
inline void SA_init(){
int *x=rank,*y=height,r=N-;
for(int i=;i<r;i++)w[i]=;
for(int i=;i<n;i++)w[s[i]]++;
for(int i=;i<r;i++)w[i]+=w[i-];
for(int i=n-;i>=;i--)sa[--w[s[i]]]=i;
r=;x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=s[sa[i]]==s[sa[i-]]?r-:r++;
for(int k=;r<n;k<<=){
int yn=;
for(int i=n-k;i<n;i++)y[yn++]=i;
for(int i=;i<n;i++)
if(sa[i]>=k)y[yn++]=sa[i]-k;
for(int i=;i<r;i++)w[i]=;
for(int i=;i<n;i++)++w[x[y[i]]];
for(int i=;i<r;i++)w[i]+=w[i-];
for(int i=n-;i>=;i--)sa[--w[x[y[i]]]]=y[i];
swap(x,y);r=;x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=pan(y,sa[i],sa[i-],k)?r-:r++;
}
for(int i=;i<n;i++)rank[i]=x[i];
}
inline void LSH(){
sort(b,b+m);
m=unique(b,b+m)-b;
for(int i=;i<n;i++){
s[i]=lower_bound(b,b+m,s[i])-b;
}
return;
}
int main(){
scanf("%d",&n);
for(int i=n-;i>=;i--){
scanf("%d",&b[i]);
s[i]=b[i];
}
m=n;
LSH();
SA_init();
for(t=;;t++){
if(sa[t]>)break;
}
for(int i=sa[t];i<n;i++)
printf("%d\n",b[s[i]]);
for(int i=;i<sa[t];i++)
s[i+sa[t]]=s[i];
n=sa[t]*;
SA_init();
for(t=;;t++){
if(sa[t]==)continue;
if(sa[t]<(n>>))break;
}
for(int i=sa[t];i<(n>>);i++)
printf("%d\n",b[s[i]]);
for(int i=;i<sa[t];i++)
printf("%d\n",b[s[i]]);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

POJ3581:Sequence——题解的更多相关文章

  1. POJ3581 Sequence —— 后缀数组

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

  2. 【CF486E】LIS of Sequence题解

    [CF486E]LIS of Sequence题解 题目链接 题意: 给你一个长度为n的序列a1,a2,...,an,你需要把这n个元素分成三类:1,2,3: 1:所有的最长上升子序列都不包含这个元素 ...

  3. [POJ3581]Sequence

    [POJ3581]Sequence 题目大意: 给定序列\(A_{1\sim n}\),其中\(A_1\)为最大的数.要把这个序列分成\(3\)个非空段,并将每一段分别反转,求能得到的字典序最小的序列 ...

  4. CF3D Least Cost Bracket Sequence 题解

    题目 This is yet another problem on regular bracket sequences. A bracket sequence is called regular, i ...

  5. POJ3581:Sequence(后缀数组)

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

  6. BZOJ4355:Play with sequence——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4355 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1] ...

  7. Pop Sequence 题解

    Pop Sequence(PAT) https://www.nowcoder.com/pat/5/problem/4090 前言: PAT上一道Stack的应用题,简化版的有<信息学一本通·普及 ...

  8. CF524F And Yet Another Bracket Sequence 题解

    题目链接 算法:后缀数组+ST表+贪心   各路题解都没怎么看懂,只会常数巨大的后缀数组+ST表,最大点用时 \(4s\), 刚好可以过... 确定合法序列长度   首先一个括号序列是合法的必须满足以 ...

  9. Codeforces 486E LIS of Sequence 题解

    题目大意: 一个序列,问其中每一个元素是否为所有最长上升子序列中的元素或是几个但不是所有最长上升子序列中的元素或一个最长上升子序列都不是. 思路: 求以每一个元素为开头和结尾的最长上升子序列长度,若两 ...

随机推荐

  1. linux_fdisk命令详解,关于分区的详解

    这篇文章写的十分详细,特别的好 fdisk -l 可以列出所有的分区,包括没有挂上的分区和usb设备.我一般用这个来查找需要挂载的分区的位置,比如挂上u盘. 实例解说Linux中fdisk分区使用方法 ...

  2. #3.14 Piday#我的圆周率日

    本文来自网易云社区 作者:马宝 圆周率日(Pi day) 2011年国际数学协会正式宣布,将每年的3月14日设为国际数学节,来源则是中国古代数学家祖冲之的圆周率."终极"圆周率日是 ...

  3. iOS SSL Pinning 保护你的 API

    随着互联网的发展,网站全面 https 化已经越来越被重视,做为 App 开发人员,从一开始就让 API 都走 SSL 也是十分必要的.但是光这样就足够了吗? SSL 可以保护线上 API 数据不被篡 ...

  4. 请求头(request)和响应头(response)

    说一说常见的请求头和相应头都有什么呢? 1)请求(客户端->服务端[request]) GET(请求的方式) /newcoder/hello.html(请求的目标资源) HTTP/1.1(请求采 ...

  5. Java 输出对象为字符串 工具类

    public static String reflectionToString(Object o){ if(o == null) return StringUtils.EMPTY; StringBui ...

  6. 【system.number】使用说明

    对象:system.number 说明:提供一系列针对数值类型的操作 目录: 方法 返回 说明 system.number.isNumber( number ) [True | False] 检测是否 ...

  7. 地牢逃脱(BFS(广度优先搜索))

    题目描述 给定一个 n 行 m 列的地牢,其中 '.' 表示可以通行的位置,'X' 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一 ...

  8. HDU 4300 Clairewd’s message (next函数的应用)

    题意:给你一个明文对密文的字母表,在给你一段截获信息,截获信息前半段是密文,后半段是明文,但不清楚它们的分界点在哪里,密文一定是完整的,明文可能是残缺的,求完整的信息串(即完整的密文+明文串). 题解 ...

  9. es6从零学习(二):promise

    es6从零学习(二):promise 一:promise的由来 某些情况下,回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称——回调地狱.由此,Promise的概念就由社区 ...

  10. hosts_allow配置了却不生效

    hosts_allow配置了却不生效 配置了两台白名单的机器,一台生效一台不生效,google后的结果都是更新libwrap.so  安装openssh等等..(问题还是没有解决) 经过对比发现,原来 ...