题解 CF494B Obsessive String
传送门。
题意
给定一个字符串
在
分析
先分析一下题目,显然,我们使用 DP 来解决这道题。
设计一个状态:
我们可以枚举最后一个子串的区间,进行转移。
首先要考虑的是,如何判断区间是否包含
我们考虑使用字符串哈希,将整一个匹配串哈希,再标记每一个区间,最后,预处理出当前左侧的第一个匹配串,令其为
p[0]=1; for(int i=1; i<=n; ++i) p[i]=p[i-1]*P; for(int i=1; i<=n; ++i) a[i]=a[i-1]*P+s[i]; for(int i=1; i<=m; ++i) wh=wh*P+t[i]; for(int i=m; i<=n; ++i) if(query(i-m+1,i)==wh) mark[i]=1; for(int i=m; i<=n; ++i) L[i]=mark[i]?i:L[i-1];
枚举了我们这一个区间后,考虑继承前面的
令枚举的左端点为
我们的
for(int i=1; i<=n; ++i) { if(!L[i]) continue; for(int j=1; j<=L[i]-m+1; ++j) { f[i]++; for(int k=1; k<=j-1; ++k) f[i]=(f[i]+f[k])%MOD; } } for(int i=1; i<=n; ++i) tot=(tot+f[i])%MOD;
时间复杂度:
接下来考虑优化这个 DP,首先将
怎么优化呢,使用前缀和。
for(int i=1; i<=n; ++i) { if(!L[i]) continue; for(int j=1;j<=L[i]-m+1;++j) f[i]=(f[i]+qzh[j-1]+1)%MOD; qzh[i]=(qzh[i-1]+f[i])%MOD; }
时间复杂度:
显然,我们依旧使用前缀和来优化。
for(int i=1; i<=n; ++i) { if(!L[i]) continue; f[i]=(sum[L[i]-m]+L[i]-m+1)%MOD; qzh[i]=(qzh[i-1]+f[i])%MOD; sum[i]=(sum[i-1]+qzh[i])%MOD; }
时间复杂度:
此时就可以愉快的 A 掉此题了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现