bzoj 2882 工艺
题目大意:
求一个数列的最小表示法
思路:
在后缀自动机上直接沿最小的边跑n步即可(学习了一波map的高端操作
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstring> 7 #include<vector> 8 #include<queue> 9 #include<map> 10 #define rep(i,s,t) for(register int i=(s);i<=(t);++i) 11 #define dwn(i,s,t) for(register int i=(s);i>=(t);--i) 12 #define ren for(register int i=fst[x];i;i=nxt[i]) 13 #define Fill(x,t) memset(x,t,sizeof(x)) 14 #define ll long long 15 #define inf 2139062143 16 #define MAXN 1200100 17 using namespace std; 18 inline int read() 19 { 20 int x=0,f=1;char ch=getchar(); 21 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 22 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 23 return x*f; 24 } 25 int n,a[MAXN],rt,lst,tot,sz[MAXN],mxlen[MAXN],rnk[MAXN],cnt[MAXN],fa[MAXN]; 26 map<int,int> tr[MAXN]; 27 inline void extend(int c) 28 { 29 int p=lst,np=lst=++tot;mxlen[np]=mxlen[p]+1,sz[np]=1; 30 for(;p&&!tr[p][c];p=fa[p]) tr[p][c]=np; 31 if(!p) {fa[np]=rt;return ;} 32 int q=tr[p][c];if(mxlen[q]==mxlen[p]+1) {fa[np]=q;return ;} 33 int nq=++tot;mxlen[nq]=mxlen[p]+1; 34 tr[nq]=tr[q],fa[nq]=fa[q],fa[np]=fa[q]=nq; 35 for(;p&&tr[p][c]==q;p=fa[p]) tr[p][c]=nq; 36 } 37 int main() 38 { 39 rt=lst=tot=1;n=read();rep(i,1,n) a[i]=read(); 40 rep(i,1,n) a[i+n]=a[i];rep(i,1,n<<1) extend(a[i]); 41 int pos=rt; 42 while(n--) 43 { 44 printf("%d ",tr[pos].begin()->first); 45 pos=tr[pos].begin()->second; 46 } 47 }