题目链接

题意:把n个数字(A1比其他数字都大)的序列分成三段,每段分别反转,问字典序最小的序列。

分析:因为A1比其他数字都大,所以反转后第一段结尾是很大的数,相当是天然的分割线,第一段可以单独考虑,即求整段的字典序最小的后缀。后面两段不能分开考虑,

例子:

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
第三步
3 2 0 5    对应输出: 3 2 0 5
可以看见这样做是不对的。。
必须要将剩下的字符串复制一遍贴在后面,然后再来求后缀数组。。。
正解:
第一步:
3 2 0 5 0 5 -1 4 8 对应输出 -1 4 8
第二步
3 2 0 5 0 5 3 2 0 5 0 5 对应输出: 0 5 0 5;
第三步
3 2 对应输出:3 2;

所以方法是剩下的反转后+剩下的反转后组成新的串,求sa(这里不用求height,只要扫一遍即可),找到符合条件的字典序最小的后缀(应该是长度为剩下的长度的前缀)。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string> typedef long long ll;
const int N = 2e5 + 5;
int a[N];
int rev[N<<1];
int sa[N<<1], rank[N<<1];
int tmp[N<<1];
int n, k; bool cmp_sa(int i, int j) {
if (rank[i] != rank[j]) {
return rank[i] < rank[j];
} else {
int ri = i + k <= n ? rank[i+k] : -1;
int rj = j + k <= n ? rank[j+k] : -1;
return ri < rj;
}
} void get_sa(int *a, int n, int *sa) {
for (int i=0; i<=n; ++i) {
sa[i] = i;
rank[i] = i < n ? a[i] : -1;
}
for (k=1; k<=n; k<<=1) {
std::sort (sa, sa+n+1, cmp_sa);
tmp[sa[0]] = 0;
for (int i=1; i<=n; ++i) {
tmp[sa[i]] = tmp[sa[i-1]] + (cmp_sa (sa[i-1], sa[i]) ? 1 : 0);
}
for (int i=0; i<=n; ++i) {
rank[i] = tmp[i];
}
}
} void run() {
std::reverse_copy (a, a+n, rev);
get_sa (rev, n, sa);
int p1;
for (int i=0; i<n; ++i) {
p1 = n - sa[i];
if (p1 >= 1 && sa[i] >= 2) {
break;
}
}
int m = n - p1;
std::reverse_copy (a+p1, a+n, rev);
std::reverse_copy (a+p1, a+n, rev+m);
get_sa (rev, m*2, sa);
int p2;
for (int i=0; i<=m*2; ++i) {
p2 = p1 + m - sa[i];
if (p2 - p1 >= 1 && p2 < n) {
break;
}
}
std::reverse (a, a+p1);
std::reverse (a+p1, a+p2);
std::reverse (a+p2, a+n);
for (int i=0; i<n; ++i) {
printf ("%d\n", a[i]);
}
} int main() {
scanf ("%d", &n);
for (int i=0; i<n; ++i) {
scanf ("%d", a+i);
}
run ();
return 0;
}

  

最新文章

  1. spring maven pom.xml设置
  2. 事务的隔离级别及mysql对应操作
  3. jquery中选择ID以什么字符开头的匹配主要用于多个上传控件的时候,id无法使用,而且class不起作用的时候
  4. CentOS Mysql自动备份 .txt
  5. POWER DESIGN
  6. Linux 下svn恢复到某一版本
  7. 程序猿的编程神器 - vim
  8. 暴力求解——除法 Division,UVa 725
  9. NuGet Package 管理工具
  10. c#计算datatable中某一列值的和
  11. oracle数据库常用的99条查询语句(转载)
  12. Python爬虫学习(二) ——————爬取前程无忧招聘信息并写入excel
  13. 【C++小白成长撸】--矩阵乘法程序
  14. linkin大话数据结构--数组
  15. org.hibernate.TransientObjectException:The given object has a null identifier
  16. pslq常用操作
  17. Python 学习笔记 - 不断更新!
  18. [NOI2018]你的名字
  19. 删除API
  20. PyCharm3.0默认快捷键

热门文章

  1. 网页(HTML)中的特殊字符
  2. Http返回码
  3. core
  4. valgrind检查C++内存泄漏
  5. poj1456(贪心+并查集)
  6. jQuery和JS原生方法对比
  7. 超好用的plsql设置
  8. SQLServer内置函数
  9. 关于 redis、memcache、mongoDB 的对比(转载)
  10. GPT vs MBR 分区 ,,, Legacy BIOS vs UEFI BIOS