Luogu P10581 蓝桥杯2024国A 重复的串 题解 [ 蓝 ] [ KMP ] [ 动态规划 ] [ 矩阵加速 ]
重复的串:KMP + dp 的板子题。
暴力 dp
设计 \(dp_{k,i,j}\) 表示主串匹配到第 \(i\) 位,模式串有 \(j\) 位已匹配完成,目前已完成 \(k\) 次匹配的方案数。
不难写出暴力的填表法转移式子,发现是平方级别的转移,所以使用填表法不行,我们尝试刷表法。
\(dp_{k,i,j}\) 要转移去的地方显然是第 \(i+1\) 位,于是我们要观察 \(j\) 里哪些是合法的,很容易就想到用 KMP 加速这个过程,因为 KMP 做的也是匹配到某一位后,求出下一位的最大匹配长度。
假设 \(m\) 为模式串的长度。
对于 \(dp_{k,i,j}\) 我们枚举第 \(i+1\) 位的字符是什么,依次和当前需要匹配的字符进行比较,然后用 KMP 的 next 数组求出下一位的最大匹配长度 \(l\):
- 当最大匹配长度为 \(m\) 时,这时候 \(k\) 就要 \(+1\),所以 \(dp_{k+1,i+1,next_l} \gets dp_{k+1,i+1,next_l}+dp_{k,i,j}\)。
- 当最大匹配长度小于 \(m\) 时,直接转移即可,\(dp_{k,i+1,l} \gets dp_{k,i+1,l}+dp_{k,i,j}\)。
时间复杂度是 \(O(k|\sum|n)\) 的,显然不可过。
矩阵优化
发现当值域非常大的 \(i\) 确定时,剩下两维的数量很小,只有 \(90\) 个值左右,考虑矩阵优化 dp。
我们把 \(i\) 这一位提取到前面来,作为快速幂的幂次即可。
构造矩阵有点难描述,看代码吧,大体就是做一遍上面的那个转移,注意细节问题就好了。
另外,当 \(j=m\) 时,不能进行转移。
时间复杂度 \(O((k|\sum|)^3 \log n)\)。
关于完整匹配
本题中,完整匹配后可以跳到 \(next\) 处,是因为这样统计方案不会重复。而其他题中,有时候完整匹配是不能直接跳回 \(next\) 的,因为完全匹配后和 \(next\) 的情况可能是不同的。这时候就要对 \(next\) 进行转移,其实就不用特判 \(next\) 就行了,下次它会自己跳回去自己的 \(next\) 的。
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
const ll mod=998244353;
int n,ne[35],m;
char c[35];
struct mat{
ll a[105][105];
mat(){memset(a,0,sizeof(a));}
mat operator*(const mat &t)const{
mat res;
for(int i=0;i<=100;i++)
{
for(int k=0;k<=100;k++)
{
for(int j=0;j<=100;j++)
{
res.a[i][j]=(res.a[i][j]+a[i][k]*t.a[k][j])%mod;
}
}
}
return res;
}
};
void construct_dp(mat &dp)
{
for(int lv=0;lv<=2;lv++)
{
int ns=1+lv*(m+1);
for(int i=ns;i<ns+m;i++)
{
for(int j=0;j<26;j++)
{
char nc=('a'+j);
int now=i-ns;
while(now&&nc!=c[now+1])now=ne[now];
if(nc==c[now+1])now++;
if(now==m)
{
if(lv==2)continue;
now=ne[now];
dp.a[i][ns+m+1+now]=(dp.a[i][ns+m+1+now]+1)%mod;
}
else dp.a[i][ns+now]=(dp.a[i][ns+now]+1)%mod;
}
}
}
}
void construct_init(mat &s){s.a[1][1]=1;}
mat qpow(mat a,ll b)
{
mat res;
for(int i=0;i<=100;i++)res.a[i][i]=1;
while(b)
{
if(b&1)res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>c+1>>n;
m=strlen(c+1);
int now=0;
for(int i=2;i<=m;i++)
{
while(now&&c[now+1]!=c[i])now=ne[now];
if(c[now+1]==c[i])now++;
ne[i]=now;
}
mat dp;
construct_dp(dp);
mat s;
construct_init(s);
dp=s*qpow(dp,n);
ll ans=0;
for(int i=1+2*(m+1);i<1+3*(m+1);i++)ans=(ans+dp.a[1][i])%mod;
cout<<ans;
return 0;
}
Luogu P10581 蓝桥杯2024国A 重复的串 题解 [ 蓝 ] [ KMP ] [ 动态规划 ] [ 矩阵加速 ]的更多相关文章
- 平方十位数(蓝桥杯第八届国赛真题 JAVA-B组)
思路:从大到小枚举,判断其平方是否不重复 答案:9814072356 //水题 标题:平方十位数 由0~9这10个数字不重复.不遗漏,可以组成很多10位数字. 这其中也有很多恰好是平方数(是某个数的平 ...
- P8701 [蓝桥杯 2019 国 B] 第八大奇迹
简要题意 你需要维护一个长度为 \(L\) 的序列 \(a\),初始时全部都是 \(0\),有 \(N\) 个操作,支持: C p x,将 \(a_p\) 修改为 \(x\). Q a b,输出 \( ...
- P8622 [蓝桥杯 2014 国 B] 生物芯片
简要题意 有 \(N\) 个二进制数,编号为 \(1\sim N\),初始时都是 \(0\).博士进行了 \(N-1\) 次操作,在第 \(i\) 次操作时,会将 \(1\sim N\) 中所有编号为 ...
- P8618 [蓝桥杯 2014 国 B] Log 大侠
简要题意 给你一个长度为 \(n\) 的正整数序列 \(a\),有 \(m\) 个询问,每一个询问给出一个区间 \([l,r]\).定义函数 \(f(x)=\lfloor\log_{2}(x)+1\r ...
- P8796 [蓝桥杯 2022 国 AC] 替换字符
题面 给定一个仅含小写英文字母的字符串 \(s\) 和 \(m\) 次操作,每次操作选择一个区间 \([l_i,r_i]\) 将 \(s\) 的该区间中的所有字母 \(x_i\) 全部替换成字母 \( ...
- 算法笔记_106:蓝桥杯练习 算法提高 周期字串(Java)
目录 1 问题描述 2 解决方案 2.1 第一印象解法(80分) 2.2 借鉴网友解法(100分) 1 问题描述 问题描述 右右喜欢听故事,但是右右的妈妈总是讲一些“从前有座山,山里有座庙,庙里有 ...
- [蓝桥杯]ALGO-87.算法训练_字串统计
问题描述 给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的. 输入格式 第一行一个 ...
- 2019年第十届蓝桥杯c++A组java/c++组题解
#include<iostream> #include<vector> using namespace std; vector <int > vec; long l ...
- 2018年蓝桥杯B组C/C++决赛题目
自己的博客排版,自我感觉略好一点. 先放上题目. 点击查看2018年蓝桥杯B组C/C++决赛题目题解 1.换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种. 小明去x星旅游, ...
- 2019年第十届蓝桥杯国赛总结(JavaA组)
JavaA组国二,可以报销了~ JA死亡之组可不是盖的,rank12的排名还是拿不到国一啊(只有五个.. 出成绩的一刻波澜不惊,毕竟去年有国一了不慌哈哈哈 不过对我来说这个结果还算意料之外吧,毕竟大三 ...
随机推荐
- MySQL 8.0 为什么会放弃查询缓存?
什么是查询缓存? 查询缓存就是将一次查询结果存储在内存中,假如下一次查询结果在内存中,就直接在内存中读取. 设计初衷 当然是提高性能,通过缓存来减少解析器.优化器.存储引擎的执行时间. MySQL查询 ...
- IOS 越狱
iOS越狱 palera1n palera1n工具支持iOS 15.0 - 16.4.1版本的越狱 支持设备,最高支持到A11芯片 iPhone 8.8P.X iPad 5 .6.7,iPad Pro ...
- 【前端】【H5 API】地理定位(获取经纬度)
H5 API 地理定位 地理定位在日常生活中应用比较广泛,例如,互联网打车.在线地图等.在HTML 5的规范中,增加了获取用户地理位置信息的接口Geolocation,开发者可以通过经纬度来获取用户的 ...
- Table flags are 0 in the data dictionary but the flags in file ./ibdata1 are 0x4800!
1.问题截图 cat /var/log/mysql/error.log 2019-01-28T09:49:57.076019Z 0 [ERROR] [FATAL] InnoDB: Table flag ...
- Qt音视频开发41-文件推流(支持网页和播放器播放并切换进度)
一.前言 本功能最初也是有一些人提过类似的需求,就是能不能将本地的音视频文件,通过纯Qt程序推流出去,然后用户可以直接在网页上播放,也可以用各种播放器播放,然后还可以任意切换播放进度,其实说白了就是个 ...
- Qt编写地图综合应用4-仪表盘
一.前言 仪表盘在很多汽车和物联网相关的系统中很常用,最直观的其实就是汽车仪表盘,这个以前主要是机械的仪表,现在逐步改成了智能的带屏带操作系统的仪表,这样美观性和拓展性功能性大大增强了,上了操作系统的 ...
- [转]springboot 监控 Actuator和Admin
参考链接: 1.springboot 监控 Actuator和Admin 2.SpringBoot:Actuator监控中心+AdminUI界面管理
- C#中使用ping命令测试远程主机网络通信是否正常
说明,使用ping工具 1.可以用来查询域名是否可以访问 2.可以用来查询域名对应的ip地址 如果远程服务器允许ping命令的前提下. 解决思路:主要使用了C#提供的Ping类,效率比较高,相应快 程 ...
- SuperMap Objects .NET知识库:SQL查询以及通配符
1 SQL 语句的构建 在SuperMap组件产品中,有许多接口都用到了过滤条件,也就是标准 SQL 语句中的 WHERE 子句部分,比如各种涉及属性查询的接口.网络分析中弧段的过滤条件.拓扑 ...
- [转]使用navicat将excel文件导入mysql数据库
excel: 注: 1.mysql里建立一张跟excel一样的表结构的表(包含id) 2.excel最好没有任何格式,只是纯值,不然会出现导入不了的错误 ----------------------- ...