zoukankan      html  css  js  c++  java
  • 【BZOJ2882】工艺 [SAM]

    工艺

    Time Limit: 10 Sec  Memory Limit: 128 MB
    [Submit][Status][Discuss]

    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

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

    Main idea

      给定一个环,问从哪一位往后走开始得到的串字典序最小。

    Solution

      我们先把串复制一遍,然后建立一个SAM,然后贪心地走最小的即可。由于SAM的种种奇特♂性质,一定可以走完n个,输出即可。由于数字很大,数组不够存,于是我们使用map。

    Code

     1 #include<iostream>    
     2 #include<string>    
     3 #include<algorithm>    
     4 #include<cstdio>    
     5 #include<cstring>    
     6 #include<cstdlib>    
     7 #include<cmath>
     8 #include<map>
     9 using namespace std;  
    10      
    11 const int ONE=1200005;
    12 const int INF=2147483640;
    13  
    14 map <int,int> a[ONE];
    15  
    16 int n,ch[ONE];
    17 int len[ONE],fa[ONE];
    18  
    19 int get()
    20 {    
    21         int res=1,Q=1;char c;    
    22         while( (c=getchar())<48 || c>57 ) 
    23         if(c=='-')Q=-1; 
    24         res=c-48;     
    25         while( (c=getchar())>=48 && c<=57 )    
    26         res=res*10+c-48;    
    27         return res*Q;    
    28 }
    29  
    30 struct SAM
    31 {
    32         int last, cnt;
    33         SAM() {last = cnt = 1;}
    34         void Add(int c)
    35         {
    36             int x = last, New = last = ++cnt;
    37             len[New] = len[x] + 1;
    38             while(x && !a[x][c]) a[x][c] = New, x = fa[x];
    39             if(!x) {fa[New] = 1; return;}
    40              
    41             int q = a[x][c];
    42             if(len[q] == len[x] + 1) fa[New] = q;
    43             else
    44             {
    45                 int Nq = ++cnt; len[Nq] = len[x] + 1;
    46                 a[Nq] = a[q];
    47                 fa[Nq] = fa[q];
    48                 fa[New] = fa[q] = Nq;
    49                 while(a[x][c] == q) a[x][c] = Nq, x = fa[x];
    50             }
    51         }
    52          
    53         void Run()
    54         {
    55             map <int,int>::iterator it;
    56             int x = 1;
    57             for(int i=1; i<=n; i++)
    58             {
    59                 it = a[x].begin();
    60                 x = it->second;
    61                 if(i!=n) printf("%d ", it->first);
    62                 else printf("%d", it->first);
    63             }
    64         }
    65 }S;
    66  
    67 int main()  
    68 {
    69         n = get();
    70         for(int i=1; i<=n; i++) ch[i] = get();
    71         for(int i=1; i<=n*2; i++) i<=n ? S.Add(ch[i]):S.Add(ch[i-n]); 
    72          
    73         S.Run();
    74 }
    View Code
  • 相关阅读:
    字节流与字符流的区别?
    启动一个线程是用run()还是start()?
    Java中的异常处理机制的简单原理和应用?
    java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
    Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
    运行时异常与一般异常有何异同?
    常用清除浮动的方法,如不清除浮动会怎样?
    多线程有几种实现方法?同步有几种实现方法?
    你所知道的集合类都有哪些?主要方法?
    至少两种方式实现自适应搜索?
  • 原文地址:https://www.cnblogs.com/BearChild/p/6866749.html
Copyright © 2011-2022 走看看