• Bzoj2882 工艺


    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 684  Solved: 309

    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

    Source

    其实就是求最小表示法。

    后缀自动机

      其实最小表示法根本用不着后缀自动机,纯当开阔思维了(才不是看到能用后缀自动机就根本没去想别的呢)

    神奇的O(n)扫描解法:http://www.cnblogs.com/SilverNebula/p/6420632.html

    先把原串扩增为两倍,然后建后缀自动机。

    后缀自动机是张DAG图,不管怎么跑都能跑到终点。那么从起点开始,每次找目标值最小的那条边走,连走n步就得到最小表示串了。

    但是这题的“字符串“是数列,不离散化开不下数组。想到用set,而set不如map方便,最终用了map。

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<map>
     8 using namespace std;
     9 const int mxn=1200010;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 int ans[mxn],act=0;
    17 struct SAM{
    18     map<int,int>t[mxn];
    19     int fa[mxn],l[mxn];
    20     int S,last,cnt;
    21     void init(){S=last=cnt=1;return;}
    22     void add(int c){
    23         int p=last,np=++cnt;last=np;
    24         l[np]=l[p]+1;
    25         for(;p && !t[p].count(c);p=fa[p])t[p][c]=np;
    26         if(!p)fa[np]=S;
    27         else{
    28             int q=t[p][c];
    29             if(l[q]==l[p]+1){fa[np]=q;}
    30             else{
    31                 int nq=++cnt;l[nq]=l[p]+1;
    32                 t[nq]=t[q];
    33                 fa[nq]=fa[q];
    34                 fa[q]=fa[np]=nq;
    35                 for(;p && t[p][c]==q;p=fa[p])t[p][c]=nq;
    36             }
    37         }
    38     }
    39     void solve(int n){
    40         int p=S,tmp=0;
    41         act=0;
    42         while(tmp<n){
    43             map<int,int>::iterator i=t[p].begin();
    44 //            printf("%d %d
    ",i->first,i->second);
    45             ans[++act]=i->first;
    46             p=i->second;
    47             tmp++;
    48         }
    49     }
    50 }sa;
    51 int n;
    52 int a[mxn];
    53 int main(){
    54     int i,j;
    55     n=read();
    56     sa.init();
    57     for(i=1;i<=n;i++){
    58         a[i]=read();
    59         sa.add(a[i]);
    60     }
    61     for(i=1;i<=n;i++) sa.add(a[i]);
    62     sa.solve(n);
    63     for(i=1;i<n;i++)printf("%d ",ans[i]);printf("%d
    ",ans[n]);
    64     return 0;
    65 }
  • 相关阅读:
    旅行锦囊
    生活智慧
    育儿锦囊
    新婚置办
    软件开发心得
    64位sql server2005安装
    Struts学习心得
    Spring学习心得
    Oracle补习班第十天
    Python----文件操作
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6420601.html
Copyright © 2020-2023  润新知