BZOJ 2882 浅谈最小表示法后缀数组求解+线性求解

这里写图片描述
世界真的很大
最小表示法这个东西很偏
一开始做这道题想到的是后缀数组的做法,nlogn的,后来借这个契机学了下最小表示法,重新写了一遍,O(n)的
想不通为什么n比nlogn快10倍。。
可能后缀数组的常数偏大吧
看题先:
description:

小敏和小燕是一对好朋友。
他们正在玩一种神奇的游戏,叫Minecraft。
他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。
他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。
两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。

input

第一行两个整数n,代表方块的数目。
第二行n个整数,每个整数按从左到右的顺序输出方块瑕疵度的值。

output

一行n个整数,代表最美观工艺品从左到右瑕疵度的值。

现在知道这东西就是一个裸的最小表示法
但第一次做的时候实在是不知道有这么个东西,思路是这样的
考虑重新排列之后字典序最小,想到后缀数组的后缀排名就是按后缀的字典序排的,但是这样有可能会忽略,若第一第二名的后缀,第一比第二短,其后一位接上第一位的时候,字典序反而会大于第二位
现在就需要解决这个东西了
考虑是让原序列从某个位置断开接到后面,可以想到是一个环,选择一个位置作为开始位置使得字典序最小
对于序列成环这种东西我们有经典解法,要记住,把原序列复制一遍接到后面,这样从原序列的每一个位置都是一个完整(多一点)的循环了
在这个构造上面求后缀排名第一的就行了,几乎没什么细节,后缀数组写熟了的话,也就10分钟吧
完整代码:

#include<stdio.h>
#include<algorithm>
using namespace std;

int n,mxn=0;
int wa[800010],wb[800010],wv[800010],ws[800010];
int rank[800010];
int sa[800010],r[
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值