
正文
Bzoj2882 工艺 [线性算法]
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
后缀自动机题解 -> http://www.cnblogs.com/SilverNebula/p/6420601.html
后缀自动机敲完,看了下排行,wc为什么别人跑得这么快?……是诶,这最小表示法用后缀自动机当然慢了
依稀记得最小表示法有超快的算法,于是去查了查,有$O(n)$的算法 (后缀自动机均摊也是$O(n)$然而常数大)
找到了这篇讲解-> http://www.cnblogs.com/mjy0724/p/4625928.html
这样就跑得飞快了(380ms,不知道那些几十ms的怎么跑出来的)
/*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,a[mxn];
int solve(){
int i,j,ed=n*;
i=;j=;
while(i<=n && j<=n){
int k=;
while(j+k<=ed && a[i+k]==a[j+k])k++;
if(j+k>ed)break;
if(a[i+k]>a[j+k]){
i=max(j,i+k+);
j=i+;
}
else j=j+k+;
}
return min(i,j);
}
int main(){
int i,j;
n=read();
for(i=;i<=n;i++){
a[i]=read();a[i+n]=a[i];
}
int ans=solve();
int ed=ans+n-;
for(i=ans;i<ed;i++)printf("%d ",a[i]);
printf("%d\n",a[ed]);
return ;
}







