形态形成场(矩阵乘法优化dp)

短信中将会涉及前\(k\)种大写字母,每个大写字母都有一个对应的替换式\(Si\),替换式中只会出现大写字母和数字,比如\(A→BB,B→CC0,C→123\),代表 \(A=12312301231230,B=1231230,C=123\)。现在对于给定的替换式,求字符 A 所代表的串有多少子串满足:

  • 这个子串为单个字符\(0\)或没有前导\(0\)。
  • 把这个子串看作一个十进制数后模\(n\)等于\(0\)。

答案对\(r\)取模。对于100%的数据,$2 \leq r \leq 10^9; 1 \leq k \leq 26; 4 \leq \left| S_i \right| \leq 100 $。

首先可以想出一个暴力dp:\(f[i][j]\)表示到第i位时,模n为j的串的个数,那么显然\(f[i][(10j+s[i])\%n]+=f[i-1][j]\)。复杂度是\(O(len\times n)\)。

但是这样只能拿60分,并不能过这道题。怎么办呢?观察一下题目,其实就是将一个字符的字符串展开以后dp,并且最多展开26层,同一个字符可能被展开多次。有没有想到矩阵优化dp?由于每次\(f[s[i]\%n]\)要加上1,因此不能用传统的矩阵递推数列,还必须在向量中加上一维常量1。为了方便,再在向量中加一维ans。向量长这样:

\((f_0, f_1, f_2,\dots,f_{n-1},ans,1)\)。

这样转移矩阵\(g[n+1][n+1]\)就可以被描述为:

\(\left [ \begin{matrix} & 第1列 & 第i列 & 第n列 & 第n+1列 \\第一行 & \dots & \dots & 1&0 \\ 第二行 & \dots & \dots & 0 & 0 \\ 第三行 & \dots & \dots & 0 & 0 \\ \dots \\ 第n行 & 0 & 0 & 1 & 0 \\ 第n+1行 & 0 & [s[i]=ch]*[ch!='0'] & 0 & 1\end{matrix} \right ]\)

先将矩阵进行处理,再把初始向量和矩阵相乘。\((0, 0, \dots,0, 1)*g[n+1][n+1]=(f_0, f_1, \dots,ans,1)\),答案就是\(f_0+ans\)。由于初始向量只有第n+1项是1,所以\(f_0+ans=g[n+1][0]+g[n+1][n]\)。

注意单个字符0不能被漏掉统计,因此需要记录串中的0的个数。

#include <cctype>
#include <cstdio>
#include <cstring>
using namespace std; typedef long long LL;
const int maxk=30, maxn=40, maxl=105;
int n, r, k, zero[maxn];
char s[maxk][maxl];
struct Mat{
int g[maxn][maxn];
}matrix[maxn], C;
void up(int &x, int y){ x+=y-r; x=(x<0?x+r:x); }
Mat& operator *(const Mat &A, const Mat &B){
memset(C.g, 0, sizeof(C.g));
for (int i=0; i<=n+1; ++i)
for (int j=0; j<=n+1; ++j)
for (int k=0; k<=n+1; ++k)
up(C.g[i][j], 1ll*A.g[i][k]*B.g[k][j]%r);
return C;
} void build(int id){ //复合字符'A'+i 所对应的转移矩阵
int len=strlen(s[id]), num;
Mat &now=matrix[id], trans;
for (int i=0; i<=n+1; ++i) now.g[i][i]=1; //相当于直接让转移矩阵相乘
for (int i=3; i<len; ++i){
if (isdigit(s[id][i])){
num=s[id][i]-'0';
memset(trans.g, 0, sizeof(trans.g));
trans.g[0][n]=trans.g[n][n]=trans.g[n+1][n+1]=1;
for (int j=0; j<n; ++j) trans.g[j][(j*10+num)%n]=1;
if (num) trans.g[n+1][num%n]=1;
else up(zero[id], 1);
now=now*trans;
} else {
num=s[id][i]-'A';
now=now*matrix[num];
up(zero[id], zero[num]);
}
}
} int main(){
scanf("%d%d%d", &n, &r, &k);
for (int i=0; i<k; ++i) scanf("%s", s[i]);
for (int i=k-1; ~i; --i) build(i);
int ans=zero[0]; up(ans, matrix[0].g[n+1][0]);
up(ans, matrix[0].g[n+1][n]);
printf("%d\n", ans);
return 0;
}

形态形成场(矩阵乘法优化dp)的更多相关文章

  1. 斐波那契数列 矩阵乘法优化DP

    斐波那契数列 矩阵乘法优化DP 求\(f(n) \%1000000007​\),\(n\le 10^{18}​\) 矩阵乘法:\(i\times k\)的矩阵\(A\)乘\(k\times j\)的矩 ...

  2. [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】

    题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...

  3. 矩阵乘法优化DP

    本文讲一下一些基本的矩阵优化DP的方法技巧. 定义三个矩阵A,B,C,其中行和列分别为$m\times n,n \times p,m\times p$,(其中行是从上往下数的,列是从左往右数的) $C ...

  4. 矩阵乘法优化DP复习

    前言 最近做毒瘤做多了--联赛难度的东西也该复习复习了. Warning:本文较长,难度分界线在"中场休息"部分,如果只想看普及难度的可以从第五部分直接到注意事项qwq 文中用(比 ...

  5. 51nod 1583 犯罪计划——矩阵乘法优化dp

    文泽想在埃及做案n次,并且想在最后不用得到惩罚.案件的被分成几种类型.比如说,案件A,当案件A被重复犯两次时,案件A将被认为不是犯罪案件,因此犯案人不用得到惩罚.也就是说,案件A被犯偶数次时,犯案人将 ...

  6. 【bzoj2476】战场的数目 矩阵乘法优化dp

    题目描述 (战场定义为对于最高的一列向两边都严格不增的“用积木搭成”的图形) 输入 输入文件最多包含25组测试数据,每个数据仅包含一行,有一个整数p(1<=p<=109),表示战场的图形周 ...

  7. 【矩阵乘法优化dp】[Codeforces 621E] Wet Shark and Blocks

    http://codeforces.com/problemset/problem/621/E E. Wet Shark and Blocks time limit per test 2 seconds ...

  8. luoguP2768: 珍珠项链(矩阵乘法优化DP)

    题意:有K种珍珠,每种N颗,求长度为1~N的项链,包含K种珍珠的项链种类数.N<=1e9, K<=30; 思路:矩阵快速幂,加个1累加前缀和即可. #include<bits/std ...

  9. bzoj 4870: [Shoi2017]组合数问题 [矩阵乘法优化dp]

    4870: [Shoi2017]组合数问题 题意:求 \[ \sum_{i=0}^{n-1} \binom{nk}{ik+r} \mod p \] \(n \le 10^9, 0\le r < ...

随机推荐

  1. 机器学习:SVM(scikit-learn 中的 SVM:LinearSVC)

    一.基础理解 Hard Margin SVM 和 Soft Margin SVM 都是解决线性分类问题,无论是线性可分的问题,还是线性不可分的问题: 和 kNN 算法一样,使用 SVM 算法前,要对数 ...

  2. L2-023. 图着色问题(暴力)

    L2-023. 图着色问题 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 图着色问题是一个著名的NP完全问题.给定无向图 G ...

  3. Git命令之创建版本

    安装 安装好Git后,将会在桌面生成 这样一个图标 运行后将会是类似控制台程序的黑色窗口,其中mingw64(参考百度百科).这样的话就可以在输入命令 例如 :git 见到下图有详细的用法表示成功否则 ...

  4. SQL基础(1)

    1.SQL简介 (1)什么是SQL? SQL指结构化查询语言 SQL使我们有能力访问数据库 SQL是一种 ANSI 的标准计算机语言 (2)SQL 能做什么? SQL面向数据库执行查询 SQL可从数据 ...

  5. 用Nmap检测漏洞

    介绍两个NSE脚本,可以检测CVE漏洞 nmap-vulners:https://github.com/vulnersCom/nmap-vulners vulscan:https://github.c ...

  6. PowerDesigner中添加约束

    唯一约束 唯一约束与创建唯一索引基本上是一回事,因为在创建唯一约束的时候,系统会创建对应的一个唯一索引,通过唯一索引来实现约束.不过唯一约束更直观的表达了对应列的唯一性,使得对应索引的目的更加清晰,所 ...

  7. 2011-12-14 调用cmd并获得输入输出+网络访问

    System.Diagnostics.Process pro = new System.Diagnostics.Process(); pro.StartInfo.FileName = "cm ...

  8. 2016.1.19 DEV Express控件GirdControl使用

    103.GridControl中添加Button RunDesigner,添加一列,设置对应字段FiledName,ColumnEdit选择ButtonEdit,此时默认风格像下拉框,需调整属性: 在 ...

  9. UML 学习[一]

    上了好久软件工程,才开始这门课程中重要部分的学习----uml图. 统一建模语言(UML,英语:Unified Modeling Language)是非专利的第三代建模和规约语言.UML是一种开放的方 ...

  10. DAY10-MYSQL库操作

    一 系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等performance_schema: MyS ...