P1368 工艺

题目

P1368 工艺
你好水题

做法

备份一下原数组,然后插入,直接输出贪心每位最小的就好了

My complete code

再见水题

#include<map>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
typedef int LL;
const LL maxn=1000000;
inline LL Read(){
	LL x(0),f(1);char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
	return x*f;
}
LL n,nod=1,lst=1;
LL a[maxn];
struct SAM{
	LL fail,len;
	map<LL,LL> son;
}S[maxn];
inline void Insert(LL c){
	LL np=++nod,p=lst; lst=nod;
	S[np].len=S[p].len+1;
	while(p&&S[p].son[c]==0){
		S[p].son[c]=np;
		p=S[p].fail;
	}
	if(!p)
	    S[np].fail=1;
	else{
		LL q=S[p].son[c];
		if(S[q].len==S[p].len+1)
		    S[np].fail=q;
		else{
			LL nq=++nod; S[nq].len=S[p].len+1;
			S[nq].son=S[q].son;
			S[nq].fail=S[q].fail;
			S[q].fail=S[np].fail=nq;
			while(p&&S[p].son[c]==q){
				S[p].son[c]=nq;
				p=S[p].fail;
			}
		}
	}
}
int main(){
	n=Read();
	for(LL i=1;i<=n;++i)
	    a[i]=Read();
	for(LL i=1;i<n;++i)
	    a[i+n]=a[i];
	for(LL i=1;i<2*n;++i)
	    Insert(a[i]);
	LL now(1);
	for(LL i=1;i<=n;++i){
		printf("%d ",S[now].son.begin()->first);
		now=S[now].son.begin()->second;
	}
	return 0;
}
posted @ 2019-01-24 23:24  y2823774827y  阅读(157)  评论(0编辑  收藏  举报