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\n",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\n",ans[n]);
64     return 0;
65 }
时间: 2024-10-13 05:22:34

Bzoj2882 工艺 [西方算法]的相关文章

Bzoj2882 工艺 [香港算法]

后缀自动机题解 -> http://www.cnblogs.com/SilverNebula/p/6420601.html 后缀自动机敲完,看了下排行,wc为什么别人跑得这么快?……是诶,这最小表示法用后缀自动机当然慢了 依稀记得最小表示法有超快的算法,于是去查了查,有O(n)的算法 (后缀自动机均摊也是O(n)然而常数大) 找到了这篇讲解-> http://www.cnblogs.com/mjy0724/p/4625928.html 这样就跑得飞快了(380ms,不知道那些几十ms的怎么跑出

bzoj2882 工艺

2882: 工艺 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 488  Solved: 212 [Submit][Status][Discuss] Description 小敏和小燕是一对好朋友. 他们正在玩一种神奇的游戏,叫Minecraft. 他们现在要做一个由方块构成的长条工艺品.但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边. 他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮. 两个工艺品美观的

bzoj2882工艺(最小表示法)

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]开头的串都会经过这里

[Strings]一些字符串题目

Trie BZOJ 3689 异或之 大意: 给定n个数,求这n个数两两异或的值中的前k小 解: 将加法换成异或就变成了一个用堆合并多个有序表的经典问题,对于加法我们按大小排序就能得到有序表,而由于这里是异或,我们需要高效地维护有序表,即对于一个数ai快速求出与它异或第k小的数. 我们将所有数按二进制建成Trie,然后在Trie的结点上记录下子树中的结束结点个数,再在Trie树上走一遍就得到了答案 BZOJ 3439 Kpm的MC密码 大意: 给定n个字符串,对于每个字符串求以这个字符串为后缀的

【BZOJ2882】工艺(后缀数组)

[BZOJ2882]工艺(后缀数组) 题面 BZOJ权限题,我爱良心洛谷 题解 最容易的想法: 把字符串在后面接一份 然后求后缀数组就行了... #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map>

【BZOJ2882】工艺(后缀自动机)

[BZOJ2882]工艺(后缀自动机) 题面 BZOJ权限题,良心洛谷 题解 还是一样的,先把串在后面接一遍 然后构建\(SAM\) 直接按照字典序输出\(n\)次就行了 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #incl

【BZOJ2882】工艺 [SAM]

工艺 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 小敏和小燕是一对好朋友. 他们正在玩一种神奇的游戏,叫Minecraft. 他们现在要做一个由方块构成的长条工艺品.但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边. 他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮. 两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵

【bzoj2882】工艺 后缀自动机+STL-map

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

知其所以然(以算法学习为例)

原文发表于2008年 其实下文的绝大部分内容对所有学习都是同理的.只不过最近在正儿巴经地学算法,而后者又不是好啃的骨头,所以平时思考总结得就自然要比学其它东西要多一些. 问题:目前几乎所有的算法书的讲解方式都是欧几里德式的.瀑布式的.自上而下的.每一个推导步骤都是精准制导直接面向目标的.由因到果,定义.引理.定理.证明一样不少,井井有条一丝不乱毫无赘肉.而实际上,这完全把人类大脑创造发明的步骤给反过来了.看起来是阳关大道,实际上车马不通. 而对读者来说,这就等于直接告诉你答案&做法了,然后让你去