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 }
View Code

相关文章:

  • 2022-01-20
猜你喜欢
  • 2021-09-09
  • 2022-02-16
  • 2021-05-26
  • 2021-09-16
相关资源
相似解决方案