【Codeforces Round 362 (Div 2)F】【AC自动机+矩阵快速幂】Legen... 长度为l字符串最大能够重复匹配的字符串权值
来源:互联网 发布:电视直播软件哪个好 编辑:程序博客网 时间:2024/06/09 14:12
Barney was hanging out with Nora for a while and now he thinks he may have feelings for her. Barney wants to send her a cheesy text message and wants to make her as happy as possible.
Initially, happiness level of Nora is 0. Nora loves some pickup lines like "I'm falling for you" and stuff. Totally, she knows n pickup lines, each consisting only of lowercase English letters, also some of them may be equal (in writing, but different in pronouncing or meaning though). Every time Nora sees i-th pickup line as a consecutive subsequence of Barney's text message her happiness level increases by ai. These substrings may overlap, for example, Nora will see the pickup line aa twice and the pickup line ab once in text messageaaab.
Due to texting app limits, Barney's text may have up to l characters.
Barney asked you to help him make Nora as much happy as possible, it's gonna be legen...
The first line of input contains two integers n and l (1 ≤ n ≤ 200, 1 ≤ l ≤ 1014) — the number of pickup lines and the maximum length of Barney's text.
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 100), meaning that Nora's happiness level increases by ai after every time seeing i-th pickup line.
The next n lines contain the pickup lines. i-th of them contains a single string si consisting of only English lowercase letter. Summary length of all pickup lines does not exceed 200.
All strings are not empty.
Print the only integer — the maximum possible value of Nora's happiness level after reading Barney's text.
3 63 2 1heartearthart
6
3 63 2 8heartearthart
16
An optimal answer for the first sample case is hearth containing each pickup line exactly once.
An optimal answer for the second sample case is artart.
#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }const int N = 205, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;const int G = 202;//矩阵大小struct MX{LL v[G][G];void O() { MS(v, 0); }void F() { MS(v, -63); }void E() { MS(v, -63); for (int i = 0; i < G; ++i)v[i][i] = 0; }MX operator * (const MX &b) const{MX c; c.O();for (int i = 0; i<G; i++){for (int j = 0; j<G; j++){c.v[i][j] = -1e18;for (int k = 0; k<G; k++){gmax(c.v[i][j], v[i][k] + b.v[k][j]);}}}return c;}MX operator ^ (LL p) const{MX y; y.E();MX x; MC(x.v, v);while (p){if (p & 1)y = y*x;x = x*x;p >>= 1;}return y;}}a, b, c;int id;char s[N];int fail[N];int nxt[N][26];int cnt[N];void insert(char s[], int val){int p = 1;for (int i = 0; s[i]; i++){int x = s[i] - 'a';if (nxt[p][x] == 0)nxt[p][x] = ++id;p = nxt[p][x];}cnt[p]+=val;}int getfail(int p, int x){while (p){if (nxt[p][x])return nxt[p][x];p = fail[p];}return 1;}void AC_automation(){queue<int>q;q.push(1);int pap, son;while (!q.empty()){pap = q.front(); q.pop();for (int i = 0; i<26; i++)if (nxt[pap][i]){son = nxt[pap][i];fail[son] = getfail(fail[pap], i);q.push(son);cnt[son] += cnt[fail[son]];b.v[pap][son] = cnt[son];}else{int fl = getfail(fail[pap], i);if(fl)b.v[pap][fl] = cnt[fl];else b.v[pap][1] = 0;}}}void clr(){memset(nxt, 0, (id + 2) * 4 * 26);memset(fail, 0, (id + 2) * 4);memset(cnt, 0, (id + 2) * 4);id = 1;}int n; LL m;int v[N];int main(){while (~scanf("%d%lld", &n, &m)){a.F(); a.v[1][1] = 0;b.F();clr();for (int i = 1; i <= n; ++i)scanf("%d", &v[i]);for (int i = 1; i <= n; ++i){scanf("%s", s); insert(s, v[i]);}AC_automation();c = a*(b ^ m);LL ans = 0;for (int i = 1; i <= id; ++i)gmax(ans,c.v[1][i]);printf("%lld\n", ans);}return 0;}/*【trick&&吐槽】这道题使得我对AC自动机又多了一层的了解。【题意】我们有n(200)个特殊单词,总长度不超过200。我们要构造一个长度为l(1e14)的字符串。如果字符串每包含一个给定单词i(可重叠匹配),则我们的权值计数+a[i]问你最大可以得到的权值【类型】AC自动机+矩阵快速幂【分析】首先,因为涉及到字符串的转移,所以我们会首先想到AC自动机。AC自动机的节点数不会超过200,每个点可以从fail指针中传来cnt的累积量。由AC自动机父节点向子节点转移的时候,我们会获得子节点cnt的增益。转移除了"父节点->子节点"以外,还有"节点->fail节点的转移",fail节点的转移如何实现的呢?比如当前AC自动机节点代表的字符串为abcd,然后,没有一个为abcde的节点,在这种情况下,如果我们扩展'e',就需要走到"abcde"的fail节点,比如我们有字符串节点表示"cde","abcde"的fail节点,那么,这个转移是有意义的,我们会获得"cde"的权值。参照代码,就是——pap = q.front(); q.pop();for (int i = 0; i<26; i++)if (nxt[pap][i]){son = nxt[pap][i];fail[son] = getfail(fail[pap], i);q.push(son);cnt[son] += cnt[fail[son]];b.v[pap][son] = cnt[son];}else{int fl = getfail(fail[pap], i);if(fl)b.v[pap][fl] = cnt[fl];else b.v[pap][1] = 0;}我们求出了节点之间的转移情况之后,就有了转移DP关系。但是我们需要构建的字符串太长了,于是,这个DP关系需要用快速幂来求解。但是这个快速幂有点特殊。因为转移方程是这样子的,f[nxt]=max(f[pre])+val[nxt]是一个取max的转移关系。于是,转移部分的代码就要是这个样子——for (int i = 0; i<G; i++){for (int j = 0; j<G; j++){c.v[i][j] = -1e18;for (int k = 0; k<G; k++){gmax(c.v[i][j], v[i][k] + b.v[k][j]);}}}在定义转移关系初始数组的时候,也要把其权值设置为极小值(对于一般的乘法快速幂矩阵,权值初始是设置为0的)有一点需要特别注意的是,在我们做矩阵快速幂的幂运算时,y的初值不能全部设为最小,对角线的权值要为0。因为这里的y代表的是转移n步之后额外获得的权值增量,起点是斜对角上的所有点,故而初始权值这样设置。经过之前所有步骤,我们就可以顺利AC啦。【时间复杂度&&优化】O(|字符串总长|^3)【数据】1 3100s*/
- 【Codeforces Round 362 (Div 2)F】【AC自动机+矩阵快速幂】Legen... 长度为l字符串最大能够重复匹配的字符串权值
- Codeforces Round #362 (Div. 2) F. Legen... (AC自动机 + 矩阵快速幂)
- Codeforces Round #362 (Div. 2) F. Legen...(AC自动机+矩阵快速幂)
- [Codeforces 697F] Legen... (AC自动机+取max的矩阵快速幂)
- CodeForces - 697F Legen... AC自动机+快速幂
- Codeforces 696D Legen...(AC自动机+矩阵快速幂)
- codeforces 696D Legen...(AC自动机+矩阵快速幂)
- 字符串匹配-AC自动机
- UVA 11019 Matrix Matcher AC自动机字符串矩阵匹配
- 字符串匹配之AC自动机
- 数据结构-字符串匹配AC自动机
- 字符串最大匹配长度
- Codeforces Round #358 (Div. 2) D. Alyona and Strings(两个字符串中找出k段相同的,且总长度最大)
- 字符串(2)- AC自动机
- CodeForces 696D AC自动机+DP+矩阵快速幂
- AC自动机+矩阵快速幂
- Codeforces Round #226 (Div. 2) E(矩阵快速幂)
- POJ2778----AC自动机的变形+矩阵快速幂(AC自动机和矩阵快速幂必做题)
- LeetCode OJ-292. Nim Game
- 南阳OJ 333 mdd的烦恼 欧拉函数
- linux网络配置
- 网站流量突然下降应该怎么找原因?
- c++在调用类的时候不一定非得实例化对象哦,有时候你不写系统会为你默认生成一个临时实例对象哦~
- 【Codeforces Round 362 (Div 2)F】【AC自动机+矩阵快速幂】Legen... 长度为l字符串最大能够重复匹配的字符串权值
- Linux下生成.so文件
- Win10升级后,VS2015不能调试Web程序问题
- 代理服务器
- TLB工作原理
- yii2 时间控件用法
- 10008---Maven简介(一)
- Shiro+Spring MVC整合
- 基于C++全局变量的声明与定义的详解