【CF696D】Legen...(AC自动机)(矩阵快速幂)
题目描述
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 0 . Nora loves some pickup lines like "I'm falling for you" and stuff. Totally, she knows n 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 i -th pickup line as a consecutive subsequence of Barney's text message her happiness level increases by a_{i} a
i
. These substrings may overlap, for example, Nora will see the pickup line aa twice and the pickup line ab once in text message aaab.
Due to texting app limits, Barney's text may have up to l l characters.
Barney asked you to help him make Nora as much happy as possible, it's gonna be legen...
Barney与Nora一起玩的时候,觉得自己喜欢上Nora了。他想给她发一段信息让她开心。
Nora的初始快乐值是0 。Nora喜欢“我深深地爱上你了”这样的情话。她一共知道n句情话,每句仅包含小写英文字母,其中的一些可能相同(写法相同,但读音或意思是不同的)。每次Nora在Barney的信息中看到第i句情话,她的快乐值就会增加a_ia
i
。这些情话在信息中可能重叠。例如,在aaab 中,Nora会看到aa 两次,看到ab 一次。
因为短信的长度限制,Barney的短信最长含有lll 个字符。Barney想让你帮他让Nora尽可能开心。
输入输出样例
输入 #1
3 6
3 2 1
heart
earth
art
输出 #1
6
输入 #2
3 6
3 2 8
heart
earth
art
输出 #2
16
这道题可以先把fail树建出来,应为权值是可以重叠的,所以在建fail树的同时也要更新val。
然后可以考虑DP。
\(dp[i][j]表示从fail树上点i到点j所可以带来的贡献\)
显然可以求得\(dp[i][j]\),但是N过大,所以我们考虑用矩阵快速幂加速DP。
然后求从根节点到每个节点的贡献,取最大值即可。
#include<bits/stdc++.h>
#define M 210
using namespace std;
struct data
{
long long ans[M][M];
}ans1;
int tree[M][26],cnt,val[M],sum[M*26],fail[M*26],m;
long long n,maxn;
char s[M];
queue<int> q;
void work()
{
for(int i=0;i<=cnt;i++)
{
for(int j=0;j<=25;j++)
{
ans1.ans[i][tree[i][j]]=sum[tree[i][j]];
}
}
}
data operator *(data a,data b)
{
data c;
memset(c.ans,-1,sizeof(c.ans));
for(int k=0;k<=cnt;k++)
{
for(int i=0;i<=cnt;i++)
{
if(a.ans[i][k]!=-1)
{
for(int j=0;j<=cnt;j++)
{
if(b.ans[k][j]!=-1)
{
c.ans[i][j]=max(c.ans[i][j],a.ans[i][k]+b.ans[k][j]);
}
}
}
}
}
return c;
}
void insert(int x)
{
int rt=0,len=strlen(s);
for(int i=0;i<len;i++)
{
if(!tree[rt][s[i]-'a'])
{
tree[rt][s[i]-'a']=++cnt;
}
rt=tree[rt][s[i]-'a'];
}
sum[rt]+=val[x];
}
void getfail()
{
for(int i=0;i<=25;i++)
{
if(tree[0][i])
{
q.push(tree[0][i]);
}
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<=25;i++)
{
int &v=tree[u][i];
if(!v)
{
v=tree[fail[u]][i];
continue;
}
fail[v]=tree[fail[u]][i];
sum[v]+=sum[fail[v]];
q.push(v);
}
}
}
data fastpow(data a,int b)
{
data sum=a;
while(b)
{
if(b&1)
{
sum=sum*a;
}
b>>=1;
a=a*a;
}
return sum;
}
signed main()
{
memset(ans1.ans,-1,sizeof(ans1.ans));
scanf("%lld%lld",&m,&n);
for(int i=1;i<=m;i++)
{
scanf("%lld",&val[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%s",s);
insert(i);
}
getfail();
work();
ans1=fastpow(ans1,n-1);
for(int i=0;i<=cnt;i++)
{
maxn=max(maxn,ans1.ans[0][i]);
}
printf("%lld\n",maxn);
return 0;
}
【CF696D】Legen...(AC自动机)(矩阵快速幂)的更多相关文章
- Codeforces Round #362(Div1) D Legen...(AC自动机+矩阵快速幂)
题目大意: 给定一些开心串,每个串有一个开心值,构造一个串,每包含一次开心串就会获得一个开心值,求最大获得多少开心值. 题解: 首先先建立AC自动机.(建立fail指针的时候,对val要进行累加) 然 ...
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...
- poj2778DNA Sequence (AC自动机+矩阵快速幂)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud DNA Sequence Time Limit: 1000MS Memory ...
- HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17160 Accepted: 6616 Des ...
- poj2778 ac自动机+矩阵快速幂
给m个子串,求长度为n的不包含子串的母串数,最直接的应该是暴搜,肯定tle,考虑用ac自动机 将子串建成字典树,通过next表来构造矩阵,然后用矩阵快速幂求长度为n的数量 邻接矩阵https://we ...
- HDU 2243 考研路茫茫――单词情结 ——(AC自动机+矩阵快速幂)
和前几天做的AC自动机类似. 思路简单但是代码200余行.. 假设solve_sub(i)表示长度为i的不含危险单词的总数. 最终答案为用总数(26^1+26^2+...+26^n)减去(solve_ ...
- POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂
这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...
- 考研路茫茫——单词情结 HDU - 2243 AC自动机 && 矩阵快速幂
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解
题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...
随机推荐
- C++——数组与字符串
目录 一.数组 1.1定义与初始化 1.1.1使用 1.1.2存储 1.1.3初始化 1.2作函数参数 1.3对象数组 1.3.1定义与访问 1.3.2初始化 1.3.3数组元素所属类的构造函数 二. ...
- Transactional事务提交后触发异步方法
一.问题复现 1.场景 2个service方法, 方法A中调用方法B. 方法A 是核心业务方法,涉及多张表数据变更,为了保持数据一致,用spring事务注解:@Transactional(rollba ...
- spring boot参数验证
必须要知道 简述 JSR303/JSR-349,hibernate validation,spring validation 之间的关系 JSR303 是一项标准,JSR-349 是其的升级版本,添加 ...
- The Largest Clique UVA - 11324
题文:https://vjudge.net/problem/UVA-11324 题解: 这个题目首先可以发现,只要是一个强连通分量,要么都选,要么都不选,将点权看成强连通分量的点数,所以这个题目就转化 ...
- Python高阶函数及函数柯里化
1 Python高阶函数 接收函数为参数,或者把函数作为结果返回的函数为高阶函数. 1.1 自定义sort函数 要求:仿照内建函数sorted,自行实现一个sort函数.内建函数sorted函数是返回 ...
- SpringBoot应用入门
一.项目搭建 使用IDEA,点击create new project,然后左边的spring initializr,右边SDK1.8,URL:https://start.spring.io,next ...
- 帝国CMS 6.5功能解密:网站安全防火墙使用说明
有关帝国CMS新版防火墙介绍可以查看:http://bbs.phome.net/showthread-13-136169-0.html 本文为大家讲解如何使用网站防火墙:一.配置“网站防火墙”有下面两 ...
- Oracle报错注入总结
0x00 前言 在oracle注入时候出现了数据库报错信息,可以优先选择报错注入,使用报错的方式将查询数据的结果带出到错误页面中. 使用报错注入需要使用类似 1=[报错语句],1>[报错语句], ...
- JavaScript 编译器-Babel
Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行.这意味着,你可以现在就用ES6.ES7编写程序,而不用担心现有环境是否支持. 一.全局安装babel工具 在保证n ...
- 基于STL的队列略解
什么是STL 以下内容摘自这儿. STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.它是由Alexander Stepanov.Meng Le ...