首页 > 其他 > 详细

【刷题】BZOJ 2882 工艺

时间:2018-06-09 10:52:20      阅读:251      评论:0      收藏:0      [点我收藏+]

Description

小敏和小燕是一对好朋友。

他们正在玩一种神奇的游戏,叫Minecraft。

他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。

他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。

两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。

Input

第一行两个整数n,代表方块的数目。

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

Output

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

Sample Input

10
10 9 8 7 6 5 4 3 2 1

Sample Output

1 10 9 8 7 6 5 4 3 2

HINT

【数据规模与约定】

对于20%的数据,n<=1000

对于40%的数据,n<=10000

对于100%的数据,n<=300000

Solution

由于可以循环,所以把串先复制一遍
复制后,就是在新串里找一个字典序最小的长度为 \(n\) 的子串
那么做SAM
存ch用map存,这样可以很快的把当前接受的最小字符提出来,不断提出 \(n\) 个字符,就是答案了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=300000+10;
int las=1,tot=1,fa[MAXN<<2],len[MAXN<<2],n,A[MAXN];
std::map<int,int> ch[MAXN<<2];
template<typename T> inline void read(T &x)
{
    T data=0,w=1;
    char ch=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
    if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void extend(int c)
{
    int p=las,np=++tot;
    las=np;
    len[np]=len[p]+1;
    while(p&&!ch[p][c])ch[p][c]=np,p=fa[p];
    if(!p)fa[np]=1;
    else
    {
        int q=ch[p][c];
        if(len[q]==len[p]+1)fa[np]=q;
        else
        {
            int nq=++tot;
            fa[nq]=fa[q];
            ch[nq]=ch[q];
            len[nq]=len[p]+1,fa[q]=fa[np]=nq;
            while(p&&ch[p][c]==q)ch[p][c]=nq,p=fa[p];
        }
    }
}
int main()
{
    read(n);
    for(register int i=1;i<=n;++i)read(A[i]),extend(A[i]);
    for(register int i=1;i<=n;++i)extend(A[i]);
    std::map<int,int>::iterator it;
    for(register int i=1,p=1;i<=n;++i)it=ch[p].begin(),write(it->first,' '),p=it->second;
    return 0;
}

【刷题】BZOJ 2882 工艺

原文:https://www.cnblogs.com/hongyj/p/9158670.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!