BZOJ 1009 [HNOI2008]GT考试 ——矩阵乘法 KMP
2024-09-07 14:17:46
先用KMP处理所有的转移,或者直接暴力也可以。
然后矩阵快速幂即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (ll i=j;i<=k;++i)
#define D(i,j,k) for (ll i=j;i>=k;--i)
#define ll long long
ll n,m,md;
char s[50];
ll fail[50];
struct matrix{
ll x[25][25];
void init(){memset(x,0,sizeof x);}
void build1()
{
init();
x[0][0]=1;
}
void build2()
{
init();
F(i,0,m-1) F(j,0,9)
{
ll now=i;
while (now&&s[now+1]-'0'!=j) now=fail[now];
if (s[now+1]-'0'==j) now++;
x[i][now]++;
}
}
matrix operator * (matrix a) {
matrix ret;ret.init();
F(i,0,m-1) F(j,0,m-1)
{
F(k,0,m-1)
ret.x[i][j]+=x[i][k]*a.x[k][j];
ret.x[i][j]%=md;
}
return ret;
}
void print()
{
printf("---\n");
F(i,0,m)
{
F(j,0,m) printf("%lld ",x[i][j]);
printf("\n");
}
printf("---\n\n");
}
void build3()
{
init();
F(i,0,m-1) x[i][i]=1;
}
}B,A,C;
int main()
{
scanf("%lld%lld%lld",&n,&m,&md);
scanf("%s",s+1);
for (int i=2,j=0;i<=m;++i)
{
while (j&&s[j+1]!=s[i]) j=fail[j];
if (s[j+1]==s[i]) j++;
fail[i]=j;
}
A.build1();B.build2();C.build3();
while (n)
{
if (n&1) C=C*B;
B=B*B;
n>>=1;
}
A=A*C;
int ans=0;
F(i,0,m-1) (ans+=A.x[0][i])%=md;
printf("%d\n",ans);
}
最新文章
- java占位符应用
- 在线倍增法求LCA专题
- imx6 android5.1 打开 调试串口
- [改善Java代码]构造函数尽量简化
- ### C++总结-[类成员函数]
- CF 338E Optimize! (线段树)
- Sybase数据库实现等效的mysql中group_concat功能
- 关于Java 去除空格,换行的代码
- MongoDB 3.6.9 集群搭建 - 切片+副本集
- settings设置中文admin
- 微信小程序开发笔记02
- NW.js安装原生node模块node-printer控制打印机
- Weekly Contest 133
- mySQL 约束 (Constraints):一、非空约束 NOT NULL 约束
- 重启虚拟目录或站点,不重启iis
- 突发奇想之:源码及文档,文档包括源码---xml格式的源码,文档源码合并;注释文档化,文档代码化;
- 一个";.java";的源文件中,是否可以包含多个类?(除了匿名内部类),有什么限制?
- LoadRunner截取字符串操作
- MySQL5.0、5.1、5.5、5.6功能进化
- 关于在jeecms中css,图片,html,模板是如何组装成——part2