题目

  点这里看题目。

分析

  首先对于模式串建立 AC 自动机,并且计算出每个状态\(p\)的贡献总和\(con(p)\)。

  考虑一个朴素的 DP :

  \(f(i,p)\):当前串长度为\(i\),匹配到\(p\)上的最大答案。

  设在\(p\)后加入字符\(c\)会转移到\(t(p,c)\), DP 的转移如下:

\[f(i+1,t(p,c))=\max\{f(i,p)+con(t(p,c))\}
\]

  如何表示这种转移? 我们可以尝试一下矩阵:

\[T_{i,j}=
\begin{cases}
con(j)&\exists c, t(i,c)=j\\
-\infty& otherwise
\end{cases}
\]

  并且可以再定义一种矩阵上的新运算 ' \(\cdot\) ' :

\[C=A\cdot B\Leftrightarrow C_{i,j}=\max\{A_{i,k}+B_{k,j}\}
\]

  那么我们对\(T\)进行\(L\)次\(T\cdot T\),再与初始向量\(\boldsymbol v\)积起来,即是答案。也就是说,答案为:

\[\boldsymbol v\cdot T^L
\]

  本质理解:

  我们的 DP 是在做什么?你会发现,我们实际上是在 AC 自动机的有向图上面做了一个从根出发走\(l\)步的最长路。

  那么\(T\)实际上是一个邻接矩阵,而 ' \(\cdot\) ' 的本质是枚举中转点计算出下一步的最长路。

  其实一次“乘法”就像是做了一次 Floyd ,我们是做了基于 Floyd 的快速幂运算!

代码

  1. #include <cstdio>
  2. #include <cstring>
  3. #define Tour( c ) for( int c = 0 ; c < 26 ; c ++ )
  4. typedef long long LL;
  5. const int MAXN = 205, MAXL = 205;
  6. template<typename _T>
  7. void read( _T &x )
  8. {
  9. x = 0;char s = getchar();int f = 1;
  10. while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
  11. while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
  12. x *= f;
  13. }
  14. template<typename _T>
  15. void write( _T x )
  16. {
  17. if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
  18. if( 9 < x ){ write( x / 10 ); }
  19. putchar( x % 10 + '0' );
  20. }
  21. template<typename _T>
  22. _T MAX( const _T a, const _T b )
  23. {
  24. return a > b ? a : b;
  25. }
  26. struct matrix
  27. {
  28. LL mat[MAXL][MAXL];
  29. int n, m;
  30. matrix() { m = n = 0, memset( mat, 0xc0, sizeof mat ); }
  31. matrix( const int N, const int M ) { n = N, m = M, memset( mat, 0xc0, sizeof mat ); }
  32. LL* operator [] ( const int indx ) { return mat[indx]; }
  33. matrix operator * ( matrix b )
  34. {
  35. matrix ret = matrix( n, b.m );
  36. for( int i = 1 ; i <= ret.n ; i ++ )
  37. for( int j = 1 ; j <= ret.m ; j ++ )
  38. for( int k = 1 ; k <= m ; k ++ )
  39. ret[i][j] = MAX( ret[i][j], mat[i][k] + b[k][j] );
  40. return ret;
  41. }
  42. void operator *= ( matrix b ) { *this = *this * b; }
  43. };
  44. int ch[MAXL][26], fail[MAXL], con[MAXL], q[MAXL];
  45. int a[MAXN];
  46. int N, cnt; LL L;
  47. char S[MAXL];
  48. matrix I( const int n ) { matrix ret = matrix( n, n ); for( int i = 1 ; i <= n ; i ++ ) ret[i][i] = 0; return ret; }
  49. void insert( const int contri )
  50. {
  51. int p = 0, id;
  52. for( int i = 1 ; S[i] ; i ++ )
  53. {
  54. id = S[i] - 'a';
  55. if( ! ch[p][id] ) ch[p][id] = ++ cnt;
  56. p = ch[p][id];
  57. }
  58. con[p] += contri;
  59. }
  60. void init()
  61. {
  62. int h = 1, t = 0, u, v;
  63. Tour( i ) if( ch[0][i] ) q[++ t] = ch[0][i];
  64. while( h <= t )
  65. {
  66. u = q[h ++];
  67. Tour( i )
  68. {
  69. if( v = ch[u][i] ) fail[v] = ch[fail[u]][i], q[++ t] = v;
  70. else ch[u][i] = ch[fail[u]][i];
  71. }
  72. con[u] += con[fail[u]];
  73. }
  74. }
  75. matrix qkpow( matrix base, LL indx )
  76. {
  77. matrix ret = I( base.n );
  78. while( indx )
  79. {
  80. if( indx & 1 ) ret *= base;
  81. base *= base, indx >>= 1;
  82. }
  83. return ret;
  84. }
  85. int main()
  86. {
  87. read( N ), read( L );
  88. for( int i = 1 ; i <= N ; i ++ ) read( a[i] );
  89. for( int i = 1 ; i <= N ; i ++ ) scanf( "%s", S + 1 ), insert( a[i] );
  90. init();
  91. matrix A = matrix( 1, cnt + 1 ), B = matrix( cnt + 1, cnt + 1 );
  92. for( int p = 0 ; p <= cnt ; p ++ )
  93. Tour( c )
  94. B[p + 1][ch[p][c] + 1] = MAX( B[p + 1][ch[p][c] + 1], ( LL ) con[ch[p][c]] );
  95. A[1][1] = 0;
  96. A *= qkpow( B, L );
  97. LL ans = 0;
  98. for( int p = 1 ; p <= cnt + 1 ; p ++ ) ans = MAX( ans, A[1][p] );
  99. write( ans ), putchar( '\n' );
  100. return 0;
  101. }

[CF696D]Legen...的更多相关文章

  1. 【CF696D】Legen...(AC自动机)(矩阵快速幂)

    题目描述 Barney was hanging out with Nora for a while and now he thinks he may have feelings for her. Ba ...

  2. CodeForces - 697F:Legen... (AC自动机+矩阵)

    Barney was hanging out with Nora for a while and now he thinks he may have feelings for her. Barney ...

  3. Codeforces 696 D. Legen...

    Description 每个字符串有些价值,问生成长度为 \(l\) 的字符串最多能获得多少价值,总字符数不超过 \(200\), \(l\leqslant 10^{14}\) . Sol AC自动机 ...

  4. Codeforces 696D Legen...(AC自动机 + 矩阵快速幂)

    题目大概说给几个字符串,每个字符串都有一个开心值,一个串如果包含一次这些字符串就加上对应的开心值,问长度n的串开心值最多可以是多少. POJ2778..复习下..太弱了都快不会做了.. 这个矩阵的乘法 ...

  5. [Codeforces 696D] Legen...

    题目大意: 给出一些匹配串,要造一个长度不超过L的字符串,每个匹配串有自己的价值,匹配串每次出现在字符串里都会贡献一次价值...要求可能得到的最大价值. 匹配串总长不超200,L<=10^14, ...

  6. 【Codeforces 696D】Legen...

    Codeforces 696 D 题意:给\(n\)个串,每个串有一个权值\(a_i\),现在要构造一个长度为\(l\leq 10^{14}\)的串,如果其中包含了第\(i\)个串,则会得到\(a_i ...

  7. Codeforces Round #362(Div1) D Legen...(AC自动机+矩阵快速幂)

    题目大意: 给定一些开心串,每个串有一个开心值,构造一个串,每包含一次开心串就会获得一个开心值,求最大获得多少开心值. 题解: 首先先建立AC自动机.(建立fail指针的时候,对val要进行累加) 然 ...

  8. codeforces泛做..

    前面说点什么.. 为了完成日常积累,傻逼呵呵的我决定来一发codeforces 挑水题 泛做.. 嗯对,就是泛做.. 主要就是把codeforces Div.1的ABCD都尝试一下吧0.0.. 挖坑0 ...

  9. html,css命名规范 (转)

    HTML+CSS命名规范总结 1.HTML部分 1.1添加必须的utf-8的字符集,并且使用HTML5的简洁 方式: <meta charset="utf-8"> 1. ...

随机推荐

  1. Sql Server数据库导入Excel、txt数据详解,新人必看

    转自个人原创 https://blog.csdn.net/qq_15170495/article/details/104591606 数据库的要想导入数据,列的映射很是关键,只有列名匹配好,系统才知道 ...

  2. Java的每个Thread都希望拥有自己的名称

    一. 介绍 平时工作中可能会碰到排查多线程的bug,而在排查的时候,如果线程(单个线程或者是线程池的线程)没有一个比较明确的名称,那么在排查的时候就比较头疼,因为排查问题首先需要找出“问题线程”,如果 ...

  3. Security8:权限模拟

    用户可以模拟其他用户或登陆的权限来执行查询,并且在查看用户和登录的权限时,结果会受到模拟上下文的影响.当执行EXECUTE AS命令时,原始用户的安全上下文会进行切换,除了ORIGINAL_LOGIN ...

  4. Unity中激活子物体

    void GetChildrenAndSetActive() { Transform[] imageTargetObjects = GetComponentsInChildren<Transfo ...

  5. [Android应用开发] 03.网络编程

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  6. [wordpress使用]001_环境安装

    Wordpress强大的可扩展性和易用性等功能,使得越来越多的人选择它来建立自己的博客和网站.那么新手朋友该如何入手呢,今天制作这个教程就是旨在帮助新手朋友快速入门,从而为今后WP建站打下坚实的基础. ...

  7. [Python基础]002.语法(1)

    语法(1) 变量 基本数据类型 空值 布尔值 数字 字符串 列表 元组 字典 结构嵌套 变量 定义变量 i = 10 这样就定义了一个名为 i 的变量,它的值是 10 . 变量名必须是大小写英文.数字 ...

  8. Mysql基础(四)

    ##约束 /* 含义:一种限制,用于限制表中的数据, 为了保证表中的数据的准确性和可靠性 分类:六大约束 not null: 非空,用于保证该字段的不能为空,比如姓名,学号等 default: 默认, ...

  9. SpringBoot的 HelloWorld

    SpringBoot HelloWorld 功能需求 ​ 浏览器发送hello请求,服务器接收请求并处理,相应HelloWorld字符串 1.创建一个maven工程:(jar) 2.导入SpringB ...

  10. 01 . Redis简介及部署主从复制

    简介 Remote Dictionary Server, 翻译为远程字典服务, Redis是一个完全开源的基于Key-Value的NoSQL存储系统,他是一个使用ANSIC语言编写的,遵守BSD协议, ...