很多题解每次暴力跳
f
a
i
l
fail
fail的复杂度确定是对的吗?
如果不是数据水应该随便卡到
O
(
n
2
)
O(n^2)
O(n2)吧
由于
最
小
循
环
节
=
i
−
n
x
t
[
i
]
最小循环节=i-nxt[i]
最小循环节=i−nxt[i]
于是可以得到
n
x
t
nxt
nxt
如果已经得到了
a
[
1...
i
−
1
]
a[1...i-1]
a[1...i−1]
如果
n
x
t
[
i
]
≠
0
nxt[i]\not =0
nxt[i]=0直接赋值即可
否则需要保证不能由之前的转移
即
a
[
i
]
!
=
a
[
n
x
t
[
i
−
1
]
+
1
]
,
a
[
n
x
t
[
n
x
t
[
i
−
1
]
]
]
,
a
[
n
x
t
[
n
x
t
[
n
x
t
[
i
−
1
]
]
]
]
.
.
.
.
.
a[i]!=a[nxt[i-1]+1],a[nxt[nxt[i-1]]],a[nxt[nxt[nxt[i-1]]]].....
a[i]!=a[nxt[i−1]+1],a[nxt[nxt[i−1]]],a[nxt[nxt[nxt[i−1]]]].....
由于不能直接跳
f
a
i
l
fail
fail所以维护一个前面所有
f
a
i
l
fail
fail的桶即可
#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
#define poly vector<int>
#define chemx(a,b) ((a)<(b)?(a)=(b):0)
#define chemn(a,b) ((a)>(b)?(a)=(b):0)
cs int N=100005;
int lp[N],n,nxt[N],buc[N][27],a[N];
int main(){
freopen("lx.cpp","r",stdin);
n=read();
for(int i=1;i<=n;i++)lp[i]=read(),nxt[i]=i-lp[i];
buc[0][0]=1;
for(int i=0,j=2;j<=n;j++){
if(nxt[j])a[j]=a[nxt[j]];
else {
i=nxt[j-1];
for(int k=0;k<26;k++)
if(!buc[i][k]){a[j]=k;break;}
}
memcpy(buc[j-1],buc[nxt[j-1]],sizeof(buc[nxt[j-1]]));
buc[j-1][a[j]]=1;
}
for(int i=1;i<=n;i++)putchar(a[i]+'a');
}