题目描述

一个串T是S的循环节,当且仅当存在正整数k,使得S是$T^k$(即T重复k次)的前缀,比如abcd是abcdabcdab的循环节。给定一个长度为n的仅由小写字符构成的字符串S,请对于每个k(1<=k<=n),求出S长度为k的前缀的最短循环节的长度$per_i$。字符串大师小Q觉得这个问题过于简单,于是花了一分钟将其AC了,他想检验你是否也是字符串大师。
小Q告诉你n以及$per_1,per_2,...,per_n$,请找到一个长度为n的小写字符串S,使得S能对应上per。

输入

第一行包含一个正整数n(1<=n<=100000),表示字符串的长度。
第二行包含n个正整数$per_1,per_2,...per_n$(1<=$per_i$<=i),表示每个前缀的最短循环节长度。
输入数据保证至少存在一组可行解。

输出

输出一行一个长度为n的小写字符串S,即某个满足条件的S。
若有多个可行的S,输出字典序最小的那一个。

样例输入

5
1 2 2 2 5

样例输出

ababb


题解

逆模拟KMP

首先有个易证的常用结论:1~n的最短循环节长度等于n-next[n],其中next为KMP算法中的next数组。

那么我们可以从前往后扫一遍。

当next不等于0时,由于next的定义为最长公共前后缀的长度,因此可以直接在前面的部分找到(s[next[i]])。由于题目保证有解,因此无需验证其正确性。

当next等于0时,考虑KMP算法求next的过程:对于上一个匹配位置,如果其下一个字符不等于当前字符,则当前匹配位置调整到其next的位置。如此循环直到下一个字符等于当前字符或者当前匹配位置为-1。然后next等于当前匹配位置+1。

由于当前的next等于0,意味着上一个匹配位置的任意的next的下一个字符都不等于当前字符。此时只需要循环向前重复找next的过程,并把下一个位置的字符设为不可选择。由于要求字典序最小,所以当前字符即为可以选择的字符中字典序最小的字母。

时间复杂度$O(26n)$

#include <cstdio>
#include <cstring>
int next[100010] , vis[26];
char str[100010];
int main()
{
int n , i , j;
scanf("%d" , &n);
next[0] = -1;
for(i = 1 ; i <= n ; i ++ )
{
scanf("%d" , &next[i]) , next[i] = i - next[i];
if(next[i]) str[i] = str[next[i]];
else
{
for(j = next[i - 1] ; ~j ; j = next[j]) vis[str[j + 1] - 'a'] = i;
for(j = 0 ; j < 26 ; j ++ )
if(vis[j] != i)
break;
str[i] = j + 'a';
}
}
printf("%s\n" , str + 1);
return 0;
}

【bzoj4974】字符串大师 逆模拟KMP的更多相关文章

  1. BZOJ4974:[Lydsy1708月赛]字符串大师(逆模拟KMP)

    题目描述 一个串T是S的循环节,当且仅当存在正整数k,使得S是T k  Tk (即T重复k次)的前缀,比如abcd是abcdabcdab的循环节.给定一个长度为n的仅由小写字符构成的字符串S,请对于每 ...

  2. BZOJ4974 字符串大师(kmp)

    显然最短循环节长度=i-next[i],则相当于给定next数组构造字符串.然后按照kmp的过程模拟即可.虽然这看起来是一个染色问题,但是由图的特殊性,如果next=0只要贪心地选最小的就可以了,稍微 ...

  3. bzoj4974 字符串大师

    4974: 字符串大师 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 310  Solved: 155[Submit][Status][Discuss] ...

  4. bzoj4974 字符串大师 KMP

    明显的,有$next[i] = i - pre[i]$ 根据$next[i]$构造比根据$pre[i]$简单 如果$next[i] \neq 0$,那么我们可以直接取前面的结果 否则,我们可以暴力的寻 ...

  5. 【BZOJ4974】字符串大师 KMP

    [BZOJ4974]字符串大师 Description 一个串T是S的循环节,当且仅当存在正整数k,使得S是T^k(即T重复k次)的前缀,比如abcd是abcdabcdab的循环节.给定一个长度为n的 ...

  6. BZOJ4974 八月月赛 Problem D 字符串大师 KMP

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4974 - 八月月赛 Problem D 题意概括 一个串T是S的循环节,当且仅当存在正整数k,使得 ...

  7. 【思维题 kmp 构造】bzoj4974: [Lydsy1708月赛]字符串大师

    字符串思博题这一块还是有点薄弱啊. Description 一个串T是S的循环节,当且仅当存在正整数k,使得S是T^k(即T重复k次)的前缀,比如abcd是abcdabcdab的循环节 .给定一个长度 ...

  8. BZOJ4974 大视野1708月赛 字符串大师

    传送门 题目大意 给定一个字符串的每一个前缀的最短循环节长度,求符合要求的字典序最小的字符串. 题解 给定循环节最短长度就是给定了这个字符串$kmp$的$next$数组,即$X_i=i-next_i$ ...

  9. [BZOJ4947] 字符串大师 - KMP

    4974: [Lydsy1708月赛]字符串大师 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 739  Solved: 358[Submit][Sta ...

随机推荐

  1. RDVTabBarController--可自由定制的iOS底部导航控件

    RDVTabBarController:一个十分完善的tabBarController,可以自定义角标个数,爽的停不下来. RDVTabBarController地址:RDVTabBarControl ...

  2. 最大公约数(gcd模板)

    int gcd(int a,int b) { ) { int t=a%b; a=b; b=t; } return a; }

  3. 【赛时总结】 ◇赛时·I◇ AtCoder ARC-098

    ◆赛时I◆ ARC-098 ■试题&解析■ ◆本场最水◆ C-Attention 长点儿信心吧-- [AtCoder ARC-098 C] [解析] 既然只存在左右(东西)两个朝向,那么领导右 ...

  4. Spring Cloud 入门 Consul-Server服务注册

    前面见过 Eureka服务注册,需要单独启用一个springboot项目  :这里介绍一个 spring cloud consul 服务, 只需要安装相关客户端,启动它就行: 1.安装Consul(以 ...

  5. 【yii】【php】自定义故障代码

    实际状态码: 200 操作成功 406 账号密码错误 208 请勿重复操作 401 需登陆验证 405 不容许此方法 409 验证错误

  6. 史上最强大的wordpress后台框架redux-framework安装及使用

    redux-framework的相关链接 Redux的官方网站:https://reduxframework.com/ Redux文档查询:https://docs.reduxframework.co ...

  7. Educational Codeforces Round 42D. Merge Equals(STL)

    D. Merge Equals time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  8. dfs序线段树

    dfs序+线段树,啥?如果在一棵树上,需要你修改一些节点和查询一些节点,如果直接dfs搜的话肯定超时,那用线段树?树结构不是区间啊,怎么用?用dfs序将树结构转化为一个区间,就能用线段树进行维护了. ...

  9. zeppelin的数据集的优化

    前面我们介绍了zeppelin的修改,前面由于自己的原因,对zeppelin的修改过于多,现在由于优化了,我们两个类, 一个是zeppelin-server的NotebookServer的类的broa ...

  10. 通过aop添加日志管理

    1.使用spring 的 aop 技术切到自定义注解上,所以先创建一个自定义注解类 import java.lang.annotation.*; @Target(ElementType.METHOD) ...