思路:
因为pre是长度为i的前缀的最短循环节长度,所以直接用它求出next
然后根据KMP的next的生成过程,i+1和j+1相等时next才更新,那么如果next为0,就直接把所有可以使next更新的字符全部搞掉,然后选剩下的。如果next不为0,那根据生成过程就直接为s[next]
c o d e code code
#include<iostream>
#include<cstdio>
using namespace std;
int n;
int pre[1010100], nxt[1010100];
char s[1010100];
int main()
{
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%d", &pre[i]);
nxt[0]=-1;
for(int i=1; i<=n; i++)
{
nxt[i]=i-pre[i];
if(nxt[i])
s[i]=s[nxt[i]];
else
{
char a[26]={0};
int j=nxt[i-1];
while(j>=0)
{
a[s[j+1]-'a']=1;
j=nxt[j];
}
for(j=0; j<26; j++)
if(!a[j])
{
s[i]=j+'a';
break;
}
}
}
for(int i=1; i<=n; i++)
printf("%c", s[i]);
return 0;
}