博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ1009]GT考试[矩阵快速幂+kmp]
阅读量:7214 次
发布时间:2019-06-29

本文共 2797 字,大约阅读时间需要 9 分钟。

\(f_{i,j}\) 表示X串前 \(i\) 位 匹配到A串第 \(j\) 位的方案数,因为不能匹配到A串第 \(m\) 位,所以答案是 \(\sum_{i=0}^{m-1}f_{n,i}\)

\(f[i][j] = \sum_{k=0}^{m-1} f[i-1][k] * g[k][j]\)

g[i][j] 是 从第 i 位匹配到第 j 位的方案数

\(f_{i-1} \times G=f_i\)

其实初始的 \(f_0\) 应该是[1,0,0,0,0,0....] 即 \(f_{0,0}=1\)

\(f_0\times G^n = G^n\) 的第一行 所以就没有再写一遍乘法了

namespace QvvQ {int n = in, m = in, mod = in, nxt[25];char s[24];struct Mod {  int a;  Mod(int _a) : a(_a) {}  Mod(ll _a) : a(_a % mod) {}  Mod() {}  int inv() {return Pow(a, mod - 2, mod);}  inline Mod &operator += (const int b) {a += b; if (a < 0) a += mod; else if (a >= mod) a -= mod; return *this;}  inline Mod &operator -= (const int b) {a -= b; if (a < 0) a += mod; else if (a >= mod) a -= mod; return *this;}  inline Mod &operator *= (const int b) {a = a * 1ll * b % mod; if (a < 0) a += mod; return *this;}  inline Mod &operator /= (const int b) {a = a * 1ll * Pow(b, mod - 2, mod) % mod; if (a < 0) a += mod; return *this;}  inline Mod &operator += (const Mod rhs) {return *this += rhs.a;}  inline Mod &operator -= (const Mod rhs) {return *this -= rhs.a;}  inline Mod &operator *= (const Mod rhs) {return *this *= rhs.a;}  inline Mod &operator /= (const Mod rhs) {return *this /= rhs.a;}  friend Mod inline operator + (Mod c, const Mod rhs) {return c += rhs.a;}  friend Mod inline operator - (Mod c, const Mod rhs) {return c -= rhs.a;}  friend Mod inline operator * (Mod c, const Mod rhs) {return c *= rhs.a;}  friend Mod inline operator / (Mod c, const Mod rhs) {return c /= rhs.a;}  inline Mod &operator = (const int x) {a = x; return *this;}  inline Mod &operator = (const ll x) {a = x % mod; return *this;}  inline Mod &operator = (const Mod rhs) {a = rhs.a; return *this;}};// f[i][j] = \sum_{k=0}^m-1 f[i-1][k] * g[k][j]struct Matrix {  int n;  Mod a[23][21];  Matrix(int _n = 0) {n = _n; lo0(i, n) lo0(j, n) a[i][j] = 0;}  Matrix operator * (const Matrix &rhs) const {    Matrix res(n);    lo0(k, n)    lo0(i, n) {      if (!a[i][k].a) continue;      lo(j, 0, rhs.n) res.a[i][j] += a[i][k] * 1ll * rhs.a[k][j];    }    return res;  }  Matrix operator ^ (int x) const {    Matrix res(n), A; A.n = n;    lo0(i, n) res.a[i][i] = 1;    lo0(i, n) lo0(j, n) A.a[i][j] = a[i][j];    while (x) {      if (x & 1) res = res * A;      A = A * A;      x >>= 1;    }    return res;  }} G(m);void init() {  in, s + 1;  nxt[1] = 0;  for (int i = 2, j = 0; i <= m; ++i) {    while (j && s[j + 1] != s[i]) j = nxt[j];    j += s[j + 1] == s[i], nxt[i] = j;  }  lo0(i, m)  lo(cc, '0', '9') {    int j = i;    while (j && s[j + 1] != cc) j = nxt[j];    j += s[j + 1] == cc, G.a[i][j] += 1;  }}void solve() {  //其实初始的f_0应该是[1,0,0,0,0,0....] 即f_{0,0}=1  //f_n*G_n = G_n的第一行 所以就没有再写乘法了  G = G ^ n;  Mod ans = 0;    lo0(i, m) ans += G.a[0][i];  out, ans.a;}}

转载于:https://www.cnblogs.com/storz/p/10510088.html

你可能感兴趣的文章
C++builder XE 安装控件 及输出路径
查看>>
优点和阵列的缺点,并且一个链表
查看>>
CSS3透明属性opacity
查看>>
Genymotion模拟器的安装及常见问题解决方法
查看>>
PHP 乘法口诀表
查看>>
如何彻底关闭windows update
查看>>
SpringMVC+SwfUpload进行多文件同时上传
查看>>
ASP.NET Core中的依赖注入(2):依赖注入(DI)
查看>>
Java_JAVA6动态编译的问题
查看>>
scala 日期格式转换
查看>>
Filtering Specific Columns with cut
查看>>
多线程编程1-NSThread
查看>>
反馈组态的判别
查看>>
【Web】Rest API 验证授权如何做?
查看>>
Swift 中的 @autoclosure
查看>>
多迪将企业的Python工程师定位成哪几类?
查看>>
Rom 检测
查看>>
【iOS工具】rvm、Ruby环境和CocoaPods安装使用及相关报错问题解决(2016 12 15 更新)...
查看>>
Weex学习指南
查看>>
TiDB DevCon 2019 报名开启:年度最高规格的 TiDB 技术大会
查看>>