【Codeforces 113B】Petr#
Codeforces 113 B
题意:有一个母串\(S\)以及两个串\(S_{begin}\)和\(S_{end}\),问\(S\)中以\(S_{begin}\)为开头并且以\(S_{end}\)为结尾的不同子串的个数。
思路1(后缀自动机):
首先肯定要把后缀自动机构建出来(第一次一遍敲对后缀自动机祭),然后我们考虑\(S_{begin}\)(和\(S_{end}\),是对称的,不做考虑)是不是在S中作为一个子串出现,如果出现了那么看它所对应的节点是哪个,打个标记(这个操作就是在自动机上沿着\(S_{begin}\)的每个字符的那条边走,最终走到哪个节点就是\(S_{begin}\)所对应的节点。)
然后找S的每一个长度为\(|S_{begin}|\)的子串,在自动机上走一遍,如果最终的节点是\(S_{begin}\)所对应的节点,那么就说明\(S_{begin}\)在此出现了,在这一位上打标记。
枚举要求的子串的开头结尾位置,如果开头的时候\(S_{begin}\)出现了,且在结尾的时候\(S_{end}\)出现了,那么这个子串就是属于答案的。将这个子串对应的节点的这个长度的标签打一下。(这里很需要注意!!!我在写的时候直接是将这个节点的标签打上了,这样非常不对,因为一个节点的定义是长度连续的一些子串们!!!如果我们只是将这个节点打上标签,则会区分不出来长度不同的子串,导致答案减少很多。因此WA15了两次!)
看每个节点打了多少标签就好了。
思路2(后缀自动机):
首先也是构造后缀自动机。
然后我们可以找到\(S_{end}\)在自动机上对应的节点是什么。既然这个子串以 \(S_{end}\)为结尾,那么肯定是\(S_{begin}\)+\(S_{end}\)的一个后缀或\(S_{begin}\)+(一堆东西)+\(S_{end}\)。我们希望保证\(S_{begin}\)完整以便计算答案。所以我们需要将\(S_{end}\)的答案加到\(S_{begin}\)头上。
这里用的方法是这样的:
首先将end的值加到parent树的子树中(parent树就是将所有节点的link指向的值向它们自己连边后的树),
其次将所有的节点的值加到go的dag中这个节点的所有父亲们头上。
这样做的结果就是每一个节点\(u\)的值就是从\(u\)表示的某个子串开始之后以\(S_{end}\)为结尾的不同子串个数
那么答案就应该是\(S_{begin}\)所对应的节点。
但是如果直接这样交上去会\(wa30\),说明还有一些问题。
对此,freak93在最后做了一些处理,使得他的程序可以AC:
按照\(S_{end}\)的顺序在自动机上跑,如果当前节点已经跑到了\(S_{begin}\)应该到的位置,但是长度却不对,就是说跑到了这个起始串对应的节点的其它子串内,肯定不应该取。否则如果已经跑到了长度为\(|S_{begin}|\)的节点,但是并不是\(S_{begin}\)所对应的节点,那么就肯定得跑到现在已经到的串的后缀继续看(为什么会是后缀啊。。。我觉得应该是前缀?为后面的反例埋下伏笔)
应该就是这样的?看了一天不算特别懂。。。(这里完全不对。。。
P.S.:这里的做法其实是看\(S_{begin}\)是不是\(S_{end}\)的一个子串且不是它的前缀,如果是的话就说明从\(S_{begin}\)所代表的节点可以走到\(S_{end}\)所代表的节点,
要减去一些不对的答案,比如\(S_{begin}\)在\(S_{end}\)中出现的次数,还有如果是\(S_{begin}\)在之前出现过,即说明真正是有答案的,他应该不更改答案,但是他成功地减去了之前求出来的的答案\(\times\)出现次数,所以。。。(这个方法真的很不好想啊。。。正常人不会想这种吧。。。可能他异于常人。。。
所以就被我的反例干掉了
注:反例(对于freak93在CF上AC的版本):
aabaab
aa
baab
这个的答案应该是1,但是这个程序输出了0。
我感觉好像他的后缀自动机敲错了
不是他的后缀自动机错了,而是我的调试语句写错了以至于我以为后缀自动机错了。。。
肯定是他最后修改对于\(wa30\)的错误的步骤错了(肯定不是选择跳到后缀嘛)(错误在上面说了)
思路3(后缀数组):
先用\(O(nlog^2n)\)的naive的做法求出后缀数组(就是在正常求的每一个\(2^h\)的阶段都直接sort)
然后把高度数组给求出来(我也不知道什么原理。。。反正求出来的就是排名为i的后缀和排名为i+1的后缀的最长公共前缀辣)
然后暴力(这个很有个性)地求出\(S_{begin}\)和\(S_{end}\)出现的位置们。
再想怎么补充不漏地记录答案。首先以i位置开始的子串肯定会和以i-1位置开始的子串有一段重复的,而这段重复的应该已经在i-1的时候算过了,所以i和i-1开始的后缀的最长公共前缀(高度数组)这一段不应该被i开始的子串记录。那么就很简单辣
【Codeforces 113B】Petr#的更多相关文章
- 【codeforces 760A】Petr and a calendar
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【Codeforces 986B】Petr and Permutations
[链接] 我是链接,点我呀:) [题意] 题意 [题解] n为奇数时3n和7n+1奇偶性不同 n为偶数时也是如此 然后交换任意一对数 逆序对的对数的奇偶性会发生改变一次 求出逆序对 对n讨论得出答案. ...
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
- 【codeforces 707C】Pythagorean Triples
[题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...
- 【codeforces 709D】Recover the String
[题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...
- 【codeforces 709B】Checkpoints
[题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...
- 【codeforces 709C】Letters Cyclic Shift
[题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...
- 【Codeforces 429D】 Tricky Function
[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...
随机推荐
- 最优-scroll事件的监听实现
1. 背景和目标 前端在监听scroll这类高频率触发事件时,常常需要一个监听函数来实现监听和回调处理.传统写法上利用setInterval或setTimeout来实现. 为了减小 CPU 开支,往往 ...
- CSS--使用伪选择器制作箭头图标
// 使用Transform的属性,组合translate(位移)和rotate(旋转),将生成的小矩形组合成各种箭头样式: HTML <section class="main&quo ...
- Linux 中的命令链接操作符
&& 与 || 配合 eg: cat test.sh #!/bin/bash [ -e /etc/hosts ] && echo "ok" || e ...
- python爬虫入门---第一篇:获取某一网页所有超链接
这是一个通过使用requests和BeautifulSoup库,简单爬取网站的所有超链接的小爬虫.有任何问题欢迎留言讨论. import requests from bs4 import Beauti ...
- 使用CSS兄弟选择器完成复杂垂直边距(vertical margins)的设计
-------------------sibling选择器如何在完成复杂设计要求的同时,保持CSS可读 这是web前端开发过程中开始简单逐步变的复杂的例子之一:将一篇文章中的所有元素应用垂直边距(ve ...
- Openlayer3之空间参考扩展
Openlayers默认了两种空间参考,一个是EPSG4326,一个是EPSG3857,其它的空间参考需要进行扩展才能使用.所以我们初始化时进行了如下操作: 1.将配置数据库中所有的空间参考读取出来, ...
- 教你如何使用云服务器去搭建SS
注册云服务器 (首先推荐Vultr,注册链接:https://www.vultr.com/?ref=6962741,其他云服务商如阿里云HK,Linode等亦可使用,按需选择) 这里拿Vultr举例: ...
- 自定义控件详解(五):onMeasure()、onLayout()
前言: 自定义控件的三大方法: 测量: onMeasure(): 测量自己的大小,为正式布局提供建议 布局: onLayout(): 使用layout()函数对所有子控件布局 绘制: onDraw() ...
- Kotlin入门(1)搭建Kotlin开发环境
Kotlin做为一门编程语言,已经出现好几年了,但此前在国内并不闻名.自从5月份谷歌宣布它成为Android的官方开发语言之后,Kotlin猛然窜红了,虽说短期内Kotlin无法取代Java,但对于一 ...
- Elasticsearch5.4署遇到的问题
问题一 can not run elasticsearch as root Elastic 不建议通过root用户启动ES服务器,如果非要用root启动,可以在config/jvm.options配置 ...