博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
似乎在梦中见过的样子 (KMP)
阅读量:5374 次
发布时间:2019-06-15

本文共 1112 字,大约阅读时间需要 3 分钟。

【题目描述】

「Madoka,不要相信 QB!」伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约。

这是 Modoka 的一个噩梦,也同时是上个轮回中所发生的事。为了使这一次 Madoka 不再与 QB 签订契约,Homura 决定在刚到学校的第一天就解决 QB。然而,QB 也是有许多替身的(但在第八话中的剧情显示它也有可能是无限重生的),不过,意志坚定的 Homura 是不会放弃的——她决定消灭所有可能是 QB 的东西。现在,她已感受到附近的状态,并且把它转化为一个长度为 nnn 的字符串交给了学 OI 的你。

现在你从她的话中知道,所有形似于 $A+B+A$ 的字串都是 QB 或它的替身,且 $|A|\ge k,|B|\ge 1$(位置不同其他性质相同的子串算不同子串,位置相同但拆分不同的子串算同一子串),然后你必须尽快告诉 Homura 这个答案——QB 以及它的替身的数量。

【算法】a

基本地:由于 $O(n^2)$ 就行,枚举子串左端点,计算每个子串的特征向量,对符合要求的累加。

特别地:KMP中计算的特征向量 $nxt[i]$ 表示的是以i为右端点,题目中A串的最小长度,由于题目对A的长度做了限制。于是,我们另开一个数组 $f$,记录满足A长度条件的最小长度 j,若 j 同时满足 $2*j<i$ 则累加。
收获:nxt数组本质上可以看作父节点表示法表示的一颗树,我们自根向下延申。要记录的是中间的满足条件的点。(之前最大循环节那道题 f 数组记录的就是根节点的值,不过我没意识到是棵树。。)

【代码】

#include 
#define ll long longusing namespace std;int k,n;ll ans;int nxt[20000],f[20000];char s[20000];void get_nxt(int x) { nxt[1]=0; for(int i=2,j=0;i<=n-x;i++) { while(j>0&&s[i+x]!=s[j+x+1]) j=nxt[j]; if(s[j+x+1]==s[i+x]) j++; nxt[i]=j; if(f[j]) f[i]=f[j]; else if(j>=k) f[i]=j; else f[i]=0; if(f[i]&&(f[i]<<1)

转载于:https://www.cnblogs.com/Willendless/p/9614641.html

你可能感兴趣的文章
洛谷P1005 矩阵取数游戏
查看>>
无线通信基础(一):无线网络演进
查看>>
关于python中带下划线的变量和函数 的意义
查看>>
linux清空日志文件内容 (转)
查看>>
MySQL-EXPLAIN执行计划Extra解释
查看>>
图片点击轮播(三)-----2017-04-05
查看>>
java中new一个对象和对象=null有什么区别
查看>>
01_1_准备ibatis环境
查看>>
spring注入Properties
查看>>
jmeter(五)创建web测试计划
查看>>
1305: [CQOI2009]dance跳舞 - BZOJ
查看>>
hash储存机制
查看>>
OpenLayers绘制图形
查看>>
洛谷 P1991 无线通讯网
查看>>
数据库第1,2,3范式学习
查看>>
《Linux内核设计与实现》第四章学习笔记
查看>>
Docker 安装MySQL5.7(三)
查看>>
CSS: caption-side 属性
查看>>
windows超过最大连接数解决命令
查看>>
12个大调都是什么
查看>>