题目大意:

给定一些开心串,每个串有一个开心值,构造一个串,每包含一次开心串就会获得一个开心值,求最大获得多少开心值。

题解:

首先先建立AC自动机。(建立fail指针的时候,对val要进行累加)

然后在AC自动机上跑dp

dp[i][j] = max(dp[i][j], dp[i-1][k] + v[j])

写成矩阵形式就是(Mat[i][j]表示从i到j最大获得的开心值)

C[i][j] = max(C[i][j], A[i][k]+B[k][j])

然后这个形式也可以用快速幂的形式加速!!

然后救过了!

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N = , maxc = ;
char str[];
struct Trie{
int Next[N][maxc], fail[N], tag[N];
long long val[N];
int root, L;
int newnode(){
for(int i = ; i < maxc; i++)
Next[L][i] = -;
tag[L++] = ;
return L-;
}
void init() { L = ; root = newnode(); }
void Insert(char* s, int len, int v){
int u = root;
for(int i = ; i < len; i++){
int c = s[i] - 'a';
if(Next[u][c] == -) Next[u][c] = newnode();
u = Next[u][c];
}
tag[u] = ;
val[u] += v;
}
void build(){
queue<int> Q;
fail[root] = root;
for(int i = ; i < maxc; i++){
if(Next[root][i] == -) Next[root][i] = root;
else {
fail[Next[root][i]] = root;
Q.push(Next[root][i]);
}
}
while(!Q.empty()){
int u = Q.front();
Q.pop();
val[u] += val[fail[u]];
for(int i = ; i < maxc; i++){
int &v = Next[u][i];
if(v == -){
v = Next[fail[u]][i];
} else {
Q.push(v);
fail[v] = Next[fail[u]][i];
}
}
}
}
}ac; struct Matrix{
long long Mat[][];
int n;
Matrix() {n = ; memset(Mat, , sizeof(Mat));}
Matrix(Matrix &B){
n = B.n;
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
Mat[i][j] = B.Mat[i][j];
}
Matrix operator +(const Matrix &B)const {
Matrix C;
C.n = n;
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++){
C.Mat[i][j] = -1e18;
for(int k = ; k <= n; k++)
C.Mat[i][j] = max(C.Mat[i][j], Mat[i][k] + B.Mat[k][j]);
}
return C;
}
void print(){
cout<<"*"<<endl;
for(int i = ; i <= n; i++){
for(int j = ; j <= n; j++) cout<<Mat[i][j]<<" ";
cout<<endl;
}
}
}A;
Matrix mypow(Matrix A, long long b)
{ Matrix ans = A; b--; for(; b; b >>= , A = A+A) if(b&) ans = ans+A; return ans;}
int n, val[];
long long l;
int main()
{
ac.init();
cin>>n>>l;
for(int i = ; i <= n; i++) scanf("%d", &val[i]);
for(int i = ; i <= n; i++){
cin>>str;
ac.Insert(str, strlen(str), val[i]);
}
ac.build();
A.n = ac.L-;
for(int i = ; i < ac.L; i++)
for(int j = ; j < ac.L; j++)
A.Mat[i][j] = -1e18;
for(int i = ; i < ac.L; i++){
for(int j = ; j < maxc; j++){
int v = ac.Next[i][j];
if(v == -) continue;
A.Mat[i][v] = ac.val[v];
}
}
A = mypow(A, l);
long long ans = -1e18;
for(int i = ; i < ac.L; i++) ans = max(ans, A.Mat[][i]);
cout<<ans<<endl;
return ;
}

Codeforces Round #362(Div1) D Legen...(AC自动机+矩阵快速幂)的更多相关文章

  1. POJ2778 DNA Sequence(AC自动机+矩阵快速幂)

    题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...

  2. poj2778DNA Sequence (AC自动机+矩阵快速幂)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud DNA Sequence Time Limit: 1000MS   Memory ...

  3. HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)

    背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...

  4. POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17160   Accepted: 6616 Des ...

  5. poj2778 ac自动机+矩阵快速幂

    给m个子串,求长度为n的不包含子串的母串数,最直接的应该是暴搜,肯定tle,考虑用ac自动机 将子串建成字典树,通过next表来构造矩阵,然后用矩阵快速幂求长度为n的数量 邻接矩阵https://we ...

  6. HDU 2243 考研路茫茫――单词情结 ——(AC自动机+矩阵快速幂)

    和前几天做的AC自动机类似. 思路简单但是代码200余行.. 假设solve_sub(i)表示长度为i的不含危险单词的总数. 最终答案为用总数(26^1+26^2+...+26^n)减去(solve_ ...

  7. POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

    这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...

  8. 考研路茫茫——单词情结 HDU - 2243 AC自动机 && 矩阵快速幂

    背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...

  9. POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解

    题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...

随机推荐

  1. Apache入门篇(一)之安装部署apache

    一.HTTPD特性 (1)高度模块化:core(核心) + modules(模块) = apache(2)动态模块加载DSO机制: Dynamic Shared Object(动态共享对象)(3)MP ...

  2. 创龙OMAPL138的NMI中断

    1. 不可屏蔽中断部分代码,注册中断函数,6748有几个NMI的引脚? void InterruptInit(void) { // 初始化 DSP 中断控制器 IntDSPINTCInit(); // ...

  3. 解决 idea template jsp模板中使用自定义路径 模板不显示问题

    ${} 是一个模板中的关键字,所以建立时需要用 \ 注释即可正常显示  ${APP_PATH}

  4. 二分查找的C#实现

    二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列. 查找过程 首先,假设表中元素是按升序排列, ...

  5. 【JUC源码解析】LinkedBlockingQueue

    简介 一个基于链表的阻塞队列,FIFO的顺序,head指向的元素等待时间最长,tail指向的元素等待时间最短,新元素从队列尾部添加,检索元素从队列头部开始,队列的容量,默认是Integer#MAX_V ...

  6. [转载]A cycle was detected in the build path of project

    解决Eclipse中Java工程间循环引用而报错的问题 如果我们的项目包含多个工程(project),而它们之间又是循环引用的关系,那么Eclipse在编译时会抛出如下一个错误信息: “A cycle ...

  7. css各种鼠标手型集合

    比较齐全的鼠标手型css在国内的网站上是没搜到这么全的比如说哪个禁止的手型:鼠标往下移动即可看到效果: html代码如下: <h1>Cursors</h1> <div c ...

  8. linux主机上,UnixBench性能测试工具使用

    1,下载  wget http://soft.laozuo.org/scripts/UnixBench5.1.3.tgz [root@VM_0_15_centos test]# [root@VM_0_ ...

  9. Just a Hook:线段树+区间修改

    E - Just a Hook In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most ...

  10. BZOJ 1559 JSOI2009 密码 状压dp+AC自动机+搜索

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1559 分析: 这个题意真的是很**啊!!!直接说每一个字符串至少出现一次不就好了吗... ...