呵呵,先贴一张图:(这就是我CodeForces的头像(至少现在是))

洛谷题目页面传送门 & CodeForces题目页面传送门

给定字符串\(a\),求它的每一个前缀,是否能被表示成\(m+1\)个字符串\(A\)和\(m\)个字符串\(B\)交错相连的形式,即求\(\forall i\in[1,|a|],\left[\exists A,\exists B,a_{1\sim i}=\underbrace{A+B+A+\cdots+A+B+A}_{m+1\text{个}A,m\text{个}B}\right]\)。

\(|a|\in\left[1,10^6\right]\)。

考虑把\(A+B\)看作一个整体,这样问题就转化为了求\(a\)的每一个前缀是否能被表示成\(m\)个字符串\(S\)相连再连上一个\(S\)的前缀(可以\(=\varnothing\),也可以\(=S\))。

我们先考虑怎么在短时间内知道一个\(a\)的前缀是否可以被表示为\(m\)个\(S\)相连,如果可以就再往后扩展。这是一个非常经典的问题。设要求的是\(a\)的前缀\(a_{1\sim i}\)。首先,得满足\(m\mid i\),于是我们可以枚举\(\dfrac im\),即\(|S|\)。然后如果\(a_{1\sim i-\frac im}=a_{1+\frac im\sim i}\),那么\(a_{1\sim i}\)可以被表示为\(m\)个\(S\)相连(这个很好证吧,错位相等)。我们可以拿\(a_{1+\frac im\sim i}\)去匹配\(a_{1\sim i-\frac im}\),这个显然可以哈希,而在枚举\(|S|\)时\(a_{1\sim i-\frac im}\)永远是\(a\)的前缀,所以也可以Z算法(如果聪明的读者还不知道Z算法是什么,please点击这个)。

接下来要考虑如何往后拓展。这个比较简单,往后拓展的那段子串长度一定\(\in[0,|S|]\),并且要与\(a\)的前缀匹配。这不正是Z算法的专长吗?\(\min(|S|,z_{a,m|S|+1})\)不就是能往后拓展的最长长度吗?这个最长长度也可以哈希+二分,但那复杂度就带\(\log\)了。对了,能往后拓展最长\(z_{a,m|S|+1}\)个,就意味着\(\forall i\in[m|S|,m|S|+z_{a,m|S|+1}]\),\(a_{1\sim i}\)都能被表示成\(m+1\)个字符串\(A\)和\(m\)个字符串\(B\)交错相连的形式,这是个区间答案赋成\(1\)的操作,可以用线段树或树状数组维护,但更简单的有差分。最后被赋成\(1\)的次数若\(>0\),则答案为\(1\),否则为\(0\)。

感觉说的不太清楚。。。具体看代码吧(也不一定能看懂啊):

#include<bits/stdc++.h>
using namespace std;
const int N=1000000;
int n/*|a|*/,m/*要被表示成m+1个A与m个B交错相连的形式*/;
char a[N+5];//字符串
int z[N+1];//z数组
void z_init(){//Z算法
z[1]=n;
int zl=0,zr=0;
for(int i=2;i<=n;i++)
if(zr<i){
while(i+z[i]<=n&&a[i+z[i]]==a[1+z[i]])z[i]++;
if(z[i])zl=i,zr=i+z[i]-1;
}
else if(i+z[i-zl+1]<=zr)z[i]=z[i-zl+1];
else{
z[i]=zr-i+1;
while(i+z[i]<=n&&a[i+z[i]]==a[1+z[i]])z[i]++;
zl=i;zr=i+z[i]-1;
}
}
int d[N+1];//差分数组
int main(){
cin>>n>>m>>a+1;
z_init();
for(int i=1;i*m<=n;i++)//枚举|S|
if(z[i+1]>=i*(m-1)){//a[1~i*m]可以被表示为m个S相连
// cout<<i<<" "<<i*m+min(i,z[i*m+1])<<"\n";
d[i*m]++;//往后拓展的左端点差分数组++
if(i*m+min(i,z[i*m+1])+1<=n)d[i*m+min(i,z[i*m+1])+1]--;//往后拓展的右端点的下一个差分数组--
}
int now=0;
for(int i=1;i<=n;i++){
now+=d[i];//现在now为i的答案被赋成1的次数
cout<<!!now;//转为bool值
}
return 0;
}

CodeForces 526D Om Nom and Necklace的更多相关文章

  1. Codeforces 526D - Om Nom and Necklace 【KMP】

    ZeptoLab Code Rush 2015 D. Om Nom and Necklace [题意] 给出一个字符串s,判断其各个前缀是否是 ABABA…ABA的形式(A和B都可以为空,且A有Q+1 ...

  2. Codeforces 526D Om Nom and Necklace (KMP)

    http://codeforces.com/problemset/problem/526/D 题意 给定一个串 T,对它的每一个前缀能否写成 A+B+A+B+...+B+A+B+A+B+...+B+A ...

  3. Codeforces - ZeptoLab Code Rush 2015 - D. Om Nom and Necklace:字符串

    D. Om Nom and Necklace time limit per test 1 second memory limit per test 256 megabytes input standa ...

  4. Codeforces 526.D Om Nom and Necklace

    D. Om Nom and Necklace time limit per test 1 second memory limit per test 256 megabytes input standa ...

  5. Codeforces C - Om Nom and Candies

    C - Om Nom and Candies 思路:贪心+思维(或者叫数学).假设最大值max(wr,wb)为wr,当c/wr小于√c时,可以枚举r糖的数量(从0到c/wr),更新答案,复杂度√c:否 ...

  6. 【Codeforces 526D】Om Nom and Necklace

    Codeforces 526 D 题意:给一个字符串,求每个前缀是否能表示成\(A+B+A+B+\dots+A\)(\(k\)个\(A+B\))的形式. 思路1:求出所有前缀的哈希值,以便求每个子串的 ...

  7. Codeforces ZeptoLab Code Rush 2015 D.Om Nom and Necklace(kmp)

    题目描述: 有一天,欧姆诺姆发现了一串长度为n的宝石串,上面有五颜六色的宝石.他决定摘取前面若干个宝石来做成一个漂亮的项链. 他对漂亮的项链是这样定义的,现在有一条项链S,当S=A+B+A+B+A+. ...

  8. CF526D Om Nom and Necklace

    嘟嘟嘟 我们可以把AB看成S,则要找的串可以写成SSSSA或者SSSSS.假设S出现了Q次,那么A出现了Q % k次,则B出现了 Q / k - Q % k次. 当ABABA是SSS的形式时,B可以为 ...

  9. 【Henu ACM Round#16 F】Om Nom and Necklace

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] KMP算法可以把"i前缀"pre[i] 分成ssssst的形式 这里t是s的前缀. 然后s其实就是pre[i]中 ...

随机推荐

  1. Spring Boot + Elasticsearch 实现索引的日常维护

    全文检索的应用越来越广泛,几乎成了互联网应用的标配,商品搜索.日志分析.历史数据归档等等,各种场景都会涉及到大批量的数据,在全文检索方面,方案无外乎Lucene.Solr.Elasticsearch三 ...

  2. Windows下通过CMD命令行程序操作MySQL数据库

    注意:如果您的MySQL没有安装在C盘下,先使用命令进入MySQL的安装目录下的bin目录中才可以进行后续操作. 方法如下:例如您安装在D盘.先输入 D:  回车即可进入D盘,再输入cd D:\您my ...

  3. Spring MVC源码(二) ----- DispatcherServlet 请求处理流程 面试必问

    前端控制器 前端控制器,即所谓的Front Controller,体现的是设计模式中的前端控制器模式.前端控制器处理所有从用户过来的请求.所有用户的请求都要通过前端控制器.SpringMVC框架和其他 ...

  4. android_ratingBar

    主文件 package cn.com.sxp;import android.app.Activity;import android.os.Bundle;import android.util.Log; ...

  5. LINUX安装源码软件经典三部曲

    这几天一直在搞suse下的mplyaer.ffmpeg等源码编译安装,总结出源码软件安装三部曲,网上称为经典三部曲. 这三步分别为: 1. ./configure [options] 2. make ...

  6. HashMap源码分析(二):看完彻底了解HashMap

    上文讲到HashMap的增加方法,现在继续 上文链接 HashMap在上一篇源码分析的文章中,如果使用put的时候如果元素数量超过threshold就会调用resize进行扩容 1.扩容机制 想要了解 ...

  7. 重新认识 async/await 语法糖

    提起.Net中的 async/await,相信很多.neter 第一反应都会是异步编程,其本质是语法糖,但继续追查下去,既然是语法糖,那么经过编译之后,真正的代码是什么样的,如何执行的?带着这些疑问, ...

  8. Android studio 混淆打包安装后报错NullPointerException int java.util.List.size()

    菜鸟的我,尝试混淆打包app...打包之前没有什么问题,混淆打包之后遇到各种问题.首先,感谢原博主的分享.解决了我的问题.谢谢. 原文地址:http://blog.csdn.net/tou_star/ ...

  9. [leetcode] 147. Insertion Sort List (Medium)

    原题 别人的思路 非常简洁 function ListNode(val) { this.val = val; this.next = null; } /** * @param {ListNode} h ...

  10. JAVA项目从运维部署到项目开发(六. Jenkins之静态页面)

    用Git托管静态页面代码,通过Jenkins部署静态页面,是再方便不过的了.本文将介绍如何通过Jenkins部署最新的静态页面代码. 一.Jenkins的配置 1.设置项目名称.参数(环境.分支)等 ...