Live2d Test Env

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;
}

 

posted @ 2018-11-11 21:28  nimphy  阅读(166)  评论(0编辑  收藏  举报