【BZOJ4974】字符串大师

Description

一个串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。

Input

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

Output

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

Sample Input

5
1 2 2 2 5

Sample Output

ababb

题解:常识:一个前缀的最小循环节=i-next[i](如果有的话),所以我们已经知道了next。

我们模拟KMP的过程,正常的KMP是如果str[i]=str[j],则更新next[i],那么我们反过来想,如果next在此处被更新了,则说明str[i]=str[j],否则str[i]!=str[j]。那么我们就得到了一堆相等和不等条件。

如何出解呢?相等条件直接做即可;不相等条件:让i的值为i可以取到的,最小的字符即可。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=100010;
int n;
char str[maxn];
int f[maxn][26],next[maxn];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,j,k;
for(i=1;i<=n;i++) next[i]=i-rd();
i=0,j=-1,next[0]=-1;
while(i<n)
{
if(next[i+1]==j+1)
{
if(j!=-1) str[i]=str[j];
else
{
for(k=0;k<26;k++) if(!f[i][k]) break;
str[i]='a'+k;
}
i++,j++;
}
else
{
f[i][str[j]-'a']=1;
j=next[j];
}
}
printf("%s",str);
return 0;
}

【BZOJ4974】字符串大师 KMP的更多相关文章

  1. bzoj4974 字符串大师 KMP

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

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

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

  3. bzoj4974 字符串大师

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

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

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

  5. bzoj 4974 [Lydsy1708月赛]字符串大师 KMP 最小循环元 构造

    LINK:字符串大师 给出一个字符串的每个前缀的最小循环元 还原字典序最小的原字符串. 一个比较显然的结论 或者说 学过KMP的都知道 对于每个前缀i求出nex数组后 那么i-nex[i]为最小循环元 ...

  6. BZOJ4974 字符串大师(kmp)

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

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

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

  8. 【bzoj4974】字符串大师 逆模拟KMP

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

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

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

随机推荐

  1. 基于Vue开发的tab切换组件

    github地址:https://github.com/MengFangui/VueTabSwitch 1.index.html <!DOCTYPE html> <html lang ...

  2. 《从零開始学Swift》学习笔记(Day 57)——Swift编码规范之凝视规范:文件凝视、文档凝视、代码凝视、使用地标凝视

    原创文章.欢迎转载.转载请注明:关东升的博客 前面说到Swift凝视的语法有两种:单行凝视(//)和多行凝视(/*...*/).这里来介绍一下他们的使用规范. 1.文件凝视 文件凝视就在每个文件开头加 ...

  3. Qt学习 之 多线程程序设计

    QT通过三种形式提供了对线程的支持.它们各自是, 一.平台无关的线程类 二.线程安全的事件投递 三.跨线程的信号-槽连接. 这使得开发轻巧的多线程Qt程序更为easy,并能充分利用多处理器机器的优势. ...

  4. 基于FPGA实现的高速串行交换模块实现方法研究

    基于FPGA实现的高速串行交换模块实现方法研究 https://wenku.baidu.com/view/9a3d501a227916888486d7ed.html

  5. MII_GMII_RGMII_RMII_SMII_SSMII_TBI_RTBI比较

    MII_GMII_RGMII_RMII_SMII_SSMII_TBI_RTBI比较 https://wenku.baidu.com/view/2e136caa8bd63186bdebbc40.html

  6. Mysql数据库分库备份,分表备份

    分库备份 #!/bin/sh DBPATH=/server/backup MYUSER=root MYPASS=oldboy123 SOCKET=/data/3306/mysql.sock MYCMD ...

  7. C++程序设计(第4版)读书笔记_C++概览:基础知识

    变量赋值 常用的变量赋值都是用“=”去赋值的 ; 但是如果把一个浮点数赋值给i的话,就会造成精度损失,在C++中最好使用初始化列表的方式“{}”给变量赋值,这样可以保证不会发生某些可能导致信息丢失的类 ...

  8. Jetty锁定文件的问题

    在windows系统上,jetty默认在运行时会锁定部署的文件.这对于需要在程序运行期间动态生成或改动某些文件就变得不能执行!对于这一点,Jetty的官网上专门有文章进行了解释:http://docs ...

  9. Android 四大组件学习之Service六

    上几节.我们学习怎样用StartServer启动一个服务,用bindServer去绑定一个服务.以及服务的生命周期,以及什么是IntentService. 也许有读者会发现,我们BindServer中 ...

  10. hadoop入门博客链接

    http://blog.itpub.net/30066956/cid-175369-list-1/