题目编号 标题 估分 正确 提交
Y 2076 Problem  A 【一本通提高篇KMP】剪花布条 --- 156 293
Y 2077 Problem  B 【一本通提高篇KMP】Radio Transmission(BZOJ1355) --- 116 265
Y 2078 Problem  C 【一本通提高篇KMP】OKR-Periods of Words --- 105 240
Y 2079 Problem  D 【一本通提高篇KMP】似乎在梦中见过的样子 --- 94 216
Y 2080 Problem  E Censoring --- 87 265

Problem A

#include<bits/stdc++.h>
using namespace std;
const int N = 1010, MOD = 1e9+7;
const int P = 131; char p[N], s[N]; //p=Pattern
int nxt[N];
int n, m;
/*
abacdaba
00100123 */
int main() {
while (1) {
scanf("%s", s + 1);
if (s[1] == '#') return 0;
scanf("%s",p+1);
int ans = 0;
n = strlen(p + 1);
m = strlen(s + 1);
for (int i = 2, j = 0; i <= n; i++) {
while (j and p[i] != p[j + 1]) j = nxt[j];
if (p[i] == p[j + 1]) j++;
nxt[i] = j;
}
for (int i = 1, j = 0; i <= m; i++) {
while (j != 0 and s[i] != p[j + 1]) {//不匹配就根据next移动
j = nxt[j];
}
if (s[i] == p[j + 1]) j++;
if (j == n) {
ans++;
j = 0;//注意这里j为0,而KMP算法中这里是j=F[j-1]+1,因为一块花纹不能重复出现在多条小饰条上
}
}
printf("%d\n",ans);
}
return 0;
}

Problem B

  • 利用 \(next\) 数组性质可得
#include<bits/stdc++.h>
using namespace std;
const int N = 1010000, MOD = 1e9+7;
const int P = 131; char p[N], s[N]; //p=Pattern
int nxt[N];
int n, m;
/*
abacdaba
00100123 */
int main() { scanf("%d%s", &n, p + 1);
for (int i = 2, j = 0; i <= n; i++) {
while (j and p[i] != p[j + 1]) j = nxt[j];
if (p[i] == p[j + 1]) j++;
nxt[i] = j;
}
printf("%d\n", n-nxt[n]); return 0;
}

Problem C

  • 利用 \(next\) 数组性质可得
#include<bits/stdc++.h>
using namespace std;
const int N = 1010000, MOD = 1e9+7;
const int P = 131;
int n,m;
char p[N];
int ne[N]; int main() {
scanf("%d%s",&n,p+1);
for(int i = 2,j = 0;i <= n;i++){
while(j and p[i] != p[j+1]) j = ne[j];
if(p[i] == p[j+1]) j++;
ne[i] = j;
// cout<<ne[i]<<" ";
}
long long ans = 0;
for(int i = 1;i <= n;i++){
int j = i;
while(ne[j] != 0) j = ne[j];
ans += i-j;
// cout<<i<<" ";
if(ne[i]) ne[i] = j;
}
cout<<ans<<endl;
return 0;
}

Problem D

  • 没懂。咕咕咕~
#include<bits/stdc++.h>
using namespace std;
const int N = 30010, MOD = 1e9+7;
const int P = 131;
char s[N];
int ne[N],ans,k,n;
void kmp(char s[]){
int len = strlen(s+1);
for(int i = 2,j = 0;i <= len;i++){
while(j and s[i] != s[j+1]) j = ne[j];
if(s[i] == s[j+1]) j++;
int p = ne[i] = j;
while(p and 2*p >= i) p = ne[p];
if(p >= k) ans++;
}
}
int main() {
cin>>s+1>>k;
n = strlen(s+1);
for(int i = 0;i <= n;i++){
kmp(s+i);
}
cout<<ans<<endl;
return 0;
}

Problem E

/*
思路:
从前到后遍历整个主串,一般情况下直接push到栈里,如果栈的大小大于等于模式串的大小而且
栈顶的前几个(确切的说,是模式串的大小)个字符的哈希值和模式串相同,就把这些值
pop掉。
该思路能够保证每次只有在栈中组成一个完整的模式串时才push掉它,不存在落下任何主串中
的模式串的情况。如果用系统栈的话最坏时间复杂度是O(2n)但是数组模拟栈的话就不需要
一个一个pop字符,直接将指向栈顶的变量调到pop所有模式串的位置即可。这样做的复杂度是
O(n).线性! */
#include <bits/stdc++.h>
using namespace std; const int N = 1e6+10,P = 131;
typedef unsigned long long ull;
char st[N];
ull h[N],p[N];
int n,s1,s2,tp;
char s[N];
char pattern[N];
ull get1(int l,int r){
return h[r]-h[l-1]*p[r-l+1];
}
int main(){
cin>>s+1>>pattern+1;
s1 = strlen(s+1);
s2 = strlen(pattern+1);
p[0] = 1;
for (int i = 1; i <= s1; i++) {
p[i] = p[i - 1] * P;
}
ull hash_pattern = 0;
for(int i = 1;i <= s2;i++) hash_pattern = hash_pattern*P+pattern[i];
if(s1 < s2){
for(int i = 1;i <= s1;i++) cout<<s[i];
return 0;
}
for(int i = 1;i <= s1;i++){
st[++tp] = s[i];
h[tp] = h[tp-1]*P+st[tp];//同下一行 if(tp >= s2 and get1(tp-s2+1,tp/*这里必须是tp!如果删除一次后i就不等于tp了,我们维护的是栈,不能使用i!这里计算的是栈中元素的哈希,如果用i的话就不同步了*/) == hash_pattern) tp = tp-s2;
}
for(int i = 1;i <= tp;i++) cout<<st[i];
return 0;
}

【完结】【一本通提高】KMP做题记录的更多相关文章

  1. $NOIp$提高组做题记录

    对了我在这里必须讲一个非常重要的事情,就是前天也就是$2019.8.21$的傍晚,我决定重新做人了$!!$ 其实之前没怎么做$Noip$题,那就从现在开始叭

  2. UOJ 做题记录

    UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...

  3. project euler做题记录

    ProjectEuler_做题记录 简单记录一下. problem 441 The inverse summation of coprime couples 神仙题.考虑答案为: \[\begin{a ...

  4. Sam做题记录

    Sam做题记录 Hihocoder 后缀自动机二·重复旋律5 求一个串中本质不同的子串数 显然,答案是 \(\sum len[i]-len[fa[i]]\) Hihocoder 后缀自动机三·重复旋律 ...

  5. 退役IV次后做题记录

    退役IV次后做题记录 我啥都不会了.... AGC023 D 如果所有的楼房都在\(S\)同一边可以直接得出答案. 否则考虑最左最右两边的票数,如果左边>=右边,那么最右边会投给左边,因为就算车 ...

  6. 退役III次后做题记录(扯淡)

    退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...

  7. 退役II次后做题记录

    退役II次后做题记录 感觉没啥好更的,咕. atcoder1219 历史研究 回滚莫队. [六省联考2017]组合数问题 我是傻逼 按照组合意义等价于\(nk\)个物品,选的物品\(\mod k\) ...

  8. BJOI做题记录

    BJOI做题记录 终于想起还要做一下历年省选题了2333 然而咕了的还是比做了的多2333 LOJ #2178. 「BJOI2017」机动训练 咕了. LOJ #2179. 「BJOI2017」树的难 ...

  9. FJOI2017前做题记录

    FJOI2017前做题记录 2017-04-15 [ZJOI2017] 树状数组 问题转化后,变成区间随机将一个数异或一,询问两个位置的值相等的概率.(注意特判询问有一个区间的左端点为1的情况,因为题 ...

  10. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

随机推荐

  1. 理解ABP的领域驱动设计

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 关于玩转ABP框架相关的文章,之前在博客园陆续写了<ABP vNext系列文 ...

  2. DeepSeek 全面指南,95% 的人都不知道的9个技巧(建议收藏)

    大家好,我是汤师爷~ 最近,DeepSeek这款AI工具爆火国内外. 虽然许多人都开始尝试使用它,但有人吐槽说,没想象中那么牛. 其实问题不在工具,很多人的使用姿势就搞错了,用大炮打蚊子,白白浪费De ...

  3. 在SOUI中将自定义配置信息写到布局文件中

    SOUI的布局XML文件保存布局必须的信息.特定场合中,用户可能会需要在布局中指定业务需要处理的属性. 比如启程输入法的皮肤.有的皮肤支持高分屏,有的皮肤不支持.对于这个场景,比较理想的方案是直接在皮 ...

  4. Java虚拟线程探索

    在Java 21中,引入了虚拟线程,这是一个非常非常重要的特性,之前一直苦苦寻找的Java协程,终于问世了.在高并发以及IO密集型的应用中,虚拟线程能极大的提高应用的性能和吞吐量. ## 什么是虚拟线 ...

  5. 我来告诉你怎么在macOS上畅玩金铲铲之战

    天选福星,灵蛇献瑞,<金铲铲之战>"天选福星"赛季好运上线!请接收这份来自<金铲铲之战>的新春邀约--"天选福星"正式回归,羁绊焕新升级 ...

  6. SQL Server 2022新功能:将数据库备份到S3兼容的对象存储

    SQL Server 2022新功能:将数据库备份到S3兼容的对象存储 本文介绍将S3兼容的对象存储用作数据库备份目标所需的概念.要求和组件. 数据库备份和恢复功能在概念上类似于使用SQL Serve ...

  7. linux监控系统行为

    1.验证电脑是否存在,一般都有 which script /usr/bin/script 2.配置profile文件,在末尾添加如下内容: vim /etc/profile ============= ...

  8. 手把手教你在个人电脑部署本地知识库(基于RAGFlow + DeepSeek [+ Ollama])

    1.    实现方案及准备工作 按照教程一步一步操作,基本没有什么太大难度,稍显麻烦的可能就是因网络问题有些资源无法下载,对于镜像无法下载的问题,文中也提供了替代的方法,但是github访问不稳定这点 ...

  9. MAC消息认证码介绍

    此MAC是密码学概念,与计算机网络不同 为什么有了摘要算法还要有MAC 摘要算法保障的是消息的完整性 归根到底就是由H(x)来保证x的完整 那么问题来了,如果我知道你所使用的摘要算法(例如中间人攻击) ...

  10. 个人文件转移工具-来自某位大神的C盘清理神器

    软件名称:个人文件转移工具 软件功能:文件转移 支持平台:Windows 软件简介:一款文件转移工具,也可用作C盘瘦身. 软件特点: ◉ "个人文件转移工具"可以把"我的 ...