码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2882工艺(最小表示法)

时间:2019-05-11 13:40:28      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:amp   bzoj   const   最小   scanf   clu   log   出现   names   

O(nlogn)的做法十分显然,有三种可以做到O(nlogn)的:1、最容易的想法:把串扩展成两倍,然后跑一遍SA求后缀数组。2、求后缀同样也可以用SAM去求解,用map存一下。3、最暴力的方法:直接二分+hash比较第一位不同的。

其实这题想要让我们用最小表示法求解,然而我不会就来学一下。很容易发现这样一个规律,如果存在s[i+k]>s[j+k],那么s[i...i+k]开头的都不会是最小表示法开头,因为s[i...i+k]=s[j...j+k],所以从s[i...i+k]开头的串都会经过这里。出现这种情况,直接i+=k即可。又简便又好写,不过这种方法很容易忘。

技术图片
#include<bits/stdc++.h>
using namespace std;
const int N=6e5+7;
int n,a[N];
int solve()
{
    int i=1,j=2;
    while(i<=n&&j<=n)
    {
        int k=0;
        while(j+k<=2*n&&a[i+k]==a[j+k])k++;
        if(j+k>2*n)break;
        if(a[i+k]>a[j+k])i=max(j,i+k+1),j=i+1;
        else j+=k+1;
    }
    return min(i,j);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i+n]=a[i];
    int pos=solve();
    for(int i=pos;i<pos+n;i++)printf("%d ",a[i]);
}
View Code

 

bzoj2882工艺(最小表示法)

标签:amp   bzoj   const   最小   scanf   clu   log   出现   names   

原文地址:https://www.cnblogs.com/hfctf0210/p/10848320.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!