BZOJ4974:[Lydsy1708月赛]字符串大师(逆模拟KMP)
题目描述
一个串T是S的循环节,当且仅当存在正整数k,使得S是
小Q告诉你n以及
输入
第一行包含一个正整数n(1<=n<=100000),表示字符串的长度。
第二行包含n个正整数
输入数据保证至少存在一组可行解。
输出
输出一行一个长度为n的小写字符串S,即某个满足条件的S。
若有多个可行的S,输出字典序最小的那一个。
样例输入
5
1 2 2 2 5
样例输出
ababb
思路:KMP的Next[i]=i-循环节。如果Next[i]!=0,那么copy前面的,否则;我们模拟下fail指针跑到的点,加标记,最后选最小的未加标记的字符。
#include<bits/stdc++.h> using namespace std; char c[100010]; int vis[30],Next[100010]; int main() { int N; scanf("%d",&N); for(int i=1,k;i<=N;i++){ scanf("%d",&Next[i]); Next[i]=i-Next[i]; if(Next[i]) c[i]=c[Next[i]]; else { k=Next[i-1]; while(k){ vis[c[k+1]-'a']=i; k=Next[k]; } if(i>1) vis[c[1]-'a']=i; for(int j=0;j<26;j++) if(vis[j]!=i){ c[i]=j+'a'; break; } } } for(int i=1;i<=N;i++) putchar(c[i]); return 0; }
It is your time to fight!