Luogu P8112 [Cnoi2021]符文破译

news/2025/2/12 8:35:36/文章来源:https://www.cnblogs.com/w9095/p/18710872

P8112 [Cnoi2021]符文破译

借用 KMP 思想优化的动态规划。

首先,用 \(dp[i]\) 表示把前 \(i\) 位的字符完全匹配需要的最少词缀数(下标均从 \(1\) 开始)。那么,我们可以从点 \(i+1\) 开始,向后逐位与字符串 \(T\) 比较。设此时匹配到了 \(T\) 中的第 \(j\) 位,如果相等,则易得转移方程:

\[dp[i+j]=\min(dp[i+j],dp[i]+1) \]

如果不相等或到达了字符串 \(T\) 末尾,则证明在此之后不会更长的有魔法词缀,可以结束这一次匹配,令 \(i=i+1\) 计算下一位即可。

很明显,这个算法的时间复杂度是 \(O(|S||T|)\) 的,当数据范围达到 \(|S|,|T|\le10^6\) 时,算法必然超时。

考虑优化这个算法,我们知道,如果不相等或到达了字符串 \(T\) 末尾,失配后是可以直接跳过一部分不可能产生新的解的数据。这样就自然而然地想到了用这个思想把单模字符串匹配优化到 \(O(|S|+|T|)\) 的 KMP 算法。

借助 KMP 的思想,首先求出字符串 \(T\)\(next\) 数组,然后开始按照 KMP 的方式匹配:(设此时文本串匹配到第 \(i\) 项,模式串匹配到第 \(j\) 项)

设置一个名为 \(now\) 的临时变量,用于存储如果匹配的最少词缀数。

可以直接逐位比较。如果相等,则按照 KMP 思想,将模式串和文本串指针一起后移,令 \(dp[i]=now\) 后比较下一位。

如果不相等,可以令 \(j=next[j]\) 之后重新计算 \(now\) 的值。因为一旦匹配失败,只能再次选择一个词缀。每次 KMP 算法在匹配失败后,会利用最长公共前后缀的性质使得文本串指针 \(i\) 不往前跳。而每次利用最长公共前后缀的性质,会改变模式串匹配的起始位置,所以需要重新计算 \(now\) 的值。可以直接用 \(dp[i-j]\) 计算出模式串匹配的起始位置的前一个位置,把 \(now\) 的值更新为 \(dp[i-j]+1\) 以保证正确性。模式串匹配到末尾也是同理。

DP 边界:\(dp[0]=1\)

DP 目标:\(dp[|S|]\)

时间复杂度:\(O(|S|+|T|)\)

注意,由于有无解的情况,所以当 \(next\) 数组跳到 \(-1\) 时,应该直接判定无解并输出 Fake。因为如果 \(next\) 数组跳到 \(-1\) 证明匹配第一个字符就失配了,此时后面没有办法再进行匹配,无解。

完整代码:(由于代码中的字符串下标是从 \(0\) 开始的,所以可能会和上文的讲解有些出入)

#include <bits/stdc++.h>
using namespace std;
int lt,ls,next1[10000010],f[10000010];
char t[10000010],s[10000010]; 
void get_next(char t[],int next[])
{int i=0,j=-1;next[0]=-1;while(i<lt){if(j==-1||t[i]==t[j])i++,j++,next[i]=j;else j=next[j];}
}bool kmp(char s[],char t[],int next[])
{int i=0,j=0,now=1;f[0]=1;while(i<ls){if(j==-1)return 0;if(s[i]==t[j])i++,j++,f[i]=now;else j=next[j],now=f[i-j]+1;if(j==lt)now=f[i-j]+1,j=next[j];}return 1;
}int main()
{scanf("%d%d%s%s",&lt,&ls,t,s);get_next(t,next1);if(!kmp(s,t,next1))printf("Fake");else printf("%d",f[ls]);return 0;
}

AC记录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/882421.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware NSX Advanced Load Balancer (NSX ALB) 30.1.2 - 多云负载均衡平台

VMware NSX Advanced Load Balancer (NSX ALB) 30.1.2 - 多云负载均衡平台VMware NSX Advanced Load Balancer (NSX ALB) 30.1.2 - 多云负载均衡平台 应用交付:多云负载均衡、Web 应用防火墙和容器 Ingress 服务 请访问原文链接:https://sysin.org/blog/vmware-nsx-alb-30/ 查…

Symantec Endpoint Protection 14.3 RU10 v14.3.12154.10000 下载

Symantec Endpoint Protection 14.3 RU10 v14.3.12154.10000 下载Symantec Endpoint Protection 14.3 RU10 v14.3.12154.10000 下载 Broadcom | SEP | SEPM | 简体中文版 | 繁体中文版 | 英文版 请访问原文链接:https://sysin.org/blog/sep-14/ 查看最新版。原创作品,转载请保…

动态编译一个新的 NativeApi 类

要动态编译一个新的 NativeApi 类,可以按照以下步骤进行:创建一个新的 NativeApi 类。 在 NativeApi 类中定义所需的方法和属性。 在 MainPage 中实例化并使用新的 NativeApi 类。using MauiPlus; using System.Reflection.Emit; using System.Reflection;namespace MauiPlus…

2025年的10个营销关键词

在瞬息万变的营销领域,把握趋势是成功的关键。本文总结了 2025 年的 10 个营销关键词,帮助你在 2025 年的营销战场上脱颖而出。 关键词一:需求细分 产品是营销的前提,产品的价值和人群越精准越细分,越容易爆。不要再喊大而泛的口号。 比如,母婴品牌世喜设计了一款“防胀气…

2025 开工大吉:明确绩效目标,合理安排计划

随着春节假期的结束,我们迎来了新的一年,也迎来了充满希望与挑战的开工日。在这个全新的起点上,“开工大吉”不仅是一句美好的祝愿,更是对我们每一位员工工作态度与效率的期许。为了在新的一年里实现更大的突破与发展,我们需要有一个明确的目标导向和高效的工作计划。在这…

容器附加存储CAS之OpenEBS快速入门

作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 目录一.CAS之OpenEBS存储机制概述1.什么是CAS2.什么是OpenEBS3.OpenEBS数据引擎4.NDM(Node Disk Manager)5.部署OpenEBS的基本流程二.部署OpenEBS 一.CAS之OpenEBS存储机制概述 1.什么是CAS Kubernetes的卷…

【CodeForces训练记录】Codeforces Round 1004 (Div. 2)

训练情况赛后反思 这场太神奇了,都在和出题人对脑电波,全是智慧题 A题 我们考虑进位的情况,例如 9999 之类的,我们发现进位对答案的影响只有 \(x - 9k + 1 = y\),判断 \(k\) 是否存在非负整数解即可点击查看代码 #include <bits/stdc++.h> // #define int long long…

短信验证码爆破

漏洞原理 短信验证码验证时间和次数无限制,存在爆破可能 短信验证码有效期:5~10min,验证码位数4位或6位,纯数字 破解方式:使用枚举逐个尝试 使用BP爆破短信验证码可以先用已有手机号确认验证码位数2.发送验证码后将验证码输入,然后登陆抓包后续和爆破操作一致如果字典太大…

【洛谷P1955】程序自动分析[NOI2015]

今天开始学习并查集 什么是并查集呢?顾名思义,就是动态维护一个方便进行合并和查找的集合 我们采用的是树状结构 也就是说,对于一开始的每个元素 它的爸爸是它自己 然后在输入两个元素的从属关系的时候,通过路径压缩,把它的爸爸直接连到根节点 因为我们只关心这个元素在这…

chorme 系统代理设置

https 需要证书 1.使用BurpSuite导出CA证书,文件导出到本地2. 谷歌浏览器添加证书 谷歌浏览器->设置->搜索"证书"->安全->管理证书->管理从windows导入的证书->受信任的根证书颁发机构->导入第一步的证书3.设置系统代理 windows系统->设置-…

picachu 越权漏洞

1. 水平越权 1.查看提示信息,提供了3个普通用户2. 登陆其中一个账户,并查看个人信息3.根据url 可以看出有用户名信息,尝试在URL中更改其他账户名,发现查看到其他用户的信息4.再次点击查看个人信息按钮,信息更改为已登陆的用户的信息5. 查看源代码发现第27行username 的值是…

windows使用Makefile时自动给可执行文件加上.exe后缀

APP := main在使用makefile的时候,一般通过变量设置自己想要编译出来的可执行文件的名字在windows平台编译出来的可执行文件是需要.exe后缀的识别当前操作系统 通过识别当前的操作系统是什么,从而确定是否添加这个后缀在windows系统中,有这个环境变量说明自己的系统是windows而…