尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

P10581 [蓝桥杯 2024 国 A] 重复的串 题解

P10581 [蓝桥杯 2024 国 A] 重复的串 题解
📅 发布时间:2026/6/20 11:29:01

单串 ACAM(可能是 KMP 自动机)+ 矩阵优化 dp。

我们设 \(dp_{k,i,j}\) 为当前字符串长为 \(k\),匹配成功 \(i\) 次,字符串结尾为 ACAM 上点 \(j\) 的方案数。

朴素转移是容易的。注意正好匹配时的边界问题。

然后发现 \(n\) 很大,\(|S|\) 很小。所以我们考虑上矩阵乘法来优化。

  • 如何构造当前字符串长为 \(k\) 时的答案矩阵(设为 \(B_k\))和转移矩阵(设为 \(A\))(下标从 \(0\) 开始编号)?

设

\[B_k= \begin{bmatrix} dp_{0,0} & dp_{0,1} & \dots & dp_{0,|S|} \\ dp_{1,0} & dp_{1,1} & \dots & dp_{1,|S|} \\ dp_{2,0} & dp_{2,1} & \dots & dp_{2,|S|} \\\end{bmatrix} \]

发现各行之间相互独立,上一行不能转移到下一行,意味着当匹配成功时无法正确转移,次数无法被更新。卒。

正确解法:

设

\[B_k= \begin{bmatrix} dp_{0,0} & \dots & dp_{0,|S|} & dp_{1,0} & \dots & dp_{1,|S|} & dp_{2,0} & \dots & dp_{2,|S|} \end{bmatrix} \]

这样当匹配成功时,次数可以正确被更新,转移正确。

然后构造转移矩阵,先初始化为 \(0\)。

令 \(base=|S|+1\)。

所以匹配 \(i\) 次在矩阵中的下标范围为 \([i\times base,i \times (base+1))\)

然后对于每个 \(i \in [0,tot)\),遍历 \(j \in [0,26)\)(就是遍历字典树),并令转移矩阵中 \(A[i][trie_{i,j}],A[i+base][trie_{i,j}+base],A[i+base+base][trie_{i,j}+base+base]\) 自增 \(1\)。意为匹配成功 \(0/1/2\) 次时,构造转移矩阵使得 \(dp_0,dp_1,dp_2\) 这三维互不干扰单独转移。

对于 \(i=tot\),遍历 \(j \in [0,26)\),并令转移矩阵中 \(A[i][trie_{i,j}+base],A[i+base][trie_{i,j}+base+base]\) 自增 \(1\)。意为由匹配成功 \(x\) 次转移到匹配成功 \(x+1\) 次。

然后对这个矩阵求它的 \(n\) 次幂,设结果为 \(X\)。

答案矩阵 \(B_n = B_0\times X\)。其实不用真正乘,发现 \(B_0\) 只有 \(B_0[0][0]=1\),所以最终答案为

\[ans=\sum_{i=2base-1}^{3base-2}X[0][i] \]

Code:

#include<bits/stdc++.h>
#define int long longusing namespace std;const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar()                                                              \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt)     \? EOF                                                                 \: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{int x=0,c=getchar(),f=0;for(;c>'9'||c<'0';f=c=='-',c=getchar());for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+(c^48);return f?-x:x;
}
inline void write(int x)
{if(x<0) x=-x,putchar('-');if(x>9)  write(x/10);putchar(x%10+'0');
}#ifndef ONLINE_JUDGE
#define ONLINE_JUDGE
#endifconst int N=31*3,mod=998244353;
int t[N][26];
int tot;
int fail[N];
struct Martix{int a[N][N]={};
}I;
Martix operator*(const Martix &x,const Martix &y)
{Martix ans;const int base=(tot+1)*3;memset(ans.a,0,sizeof(ans.a));for(int i=0;i<base;i++)for(int j=0;j<base;j++)for(int k=0;k<base;k++)(ans.a[i][j]+=x.a[i][k]*y.a[k][j]%mod)%=mod;return ans;
}void insert(const string &s)
{	int nw=0;for(char i:s){if(!t[nw][i-'a']) t[nw][i-'a']=++tot;nw=t[nw][i-'a'];}
}	Martix build()
{queue<int> q;Martix ans;memset(ans.a,0,sizeof(ans.a));for(int i=0;i<26;i++){if(t[0][i]) q.push(t[0][i]);}while(q.size()){int nw=q.front();q.pop();for(int i=0;i<26;i++){if(t[nw][i]){fail[t[nw][i]]=t[fail[nw]][i];q.push(t[nw][i]);}else t[nw][i]=t[fail[nw]][i];}}const int base=tot+1;for(int i=0;i<tot;i++)for(int j=0;j<26;j++){ans.a[i][t[i][j]]+=1;ans.a[i+base][t[i][j]+base]+=1;ans.a[i+base+base][t[i][j]+base+base]+=1;}for(int i=tot;i==tot;i++)for(int j=0;j<26;j++){ans.a[i][t[i][j]+base]+=1;ans.a[i+base][t[i][j]+base+base]+=1;}return ans;
}Martix ksm(Martix x,int p)
{Martix ans=I;while(p){if(p&1) ans=ans*x;x=x*x;p>>=1;}return ans;
}// void output(Martix x)
// {
// 	cout<<"\n------------------------------------\n\n";// 	for(int i=0;i<(tot+1)*3;i++,cout<<"\n") 
// 	for(int j=0;j<(tot+1)*3;j++) 
// 	cout<<x.a[i][j]<<" ";     
// 	// cout<<"\n------------------------------------\n\n";
// }signed main()
{#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifmemset(I.a,0,sizeof(I.a));for(int i=0;i<N;i++) I.a[i][i]=1;string s;int n;cin>>s>>n;insert(s);Martix x=build();Martix ans=ksm(x,n);int nw=0;int base=tot+1;for(int i=2*base-1;i<3*base-1;i++) (nw+=ans.a[0][i])%=mod;cout<<nw<<"\n";return 0;
}

以下是博客签名,正文无关

本文来自博客园,作者:Wy_x,转载请在文首注明原文链接:https://www.cnblogs.com/Wy-x/p/19206991

版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC-BY-NC-SA 4.0 协议)进行许可。

相关新闻

  • AQS 是什么?
  • nginx详细配置
  • 污点和容忍度

最新新闻

  • 深圳汉语培训哪个好 - 速递信息
  • 如何将数字文本转换为逼真手写体:开源工具 text-to-handwriting 的完整指南
  • 2026无锡黄金回收城市榜单:以奢响佳为代表的S+评级门店具备11项透明资质 - 商业信息快查
  • 用 AI 导出鸭极速导出内容,AI 输出无乱码,排版整洁一键落地
  • 终极React Fiber入门:理解React 16核心架构的革命性算法
  • 外墙防水常见问题解答(2026最新专家版) - 速递信息

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号