【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不太好 ...
随机推荐
- Elasticsearch全文检索学习
ElasticSearch官方网址:https://www.elastic.co ElasticSearch官方网址(中文):https://www.elastic.co/cn/ Elasticsea ...
- 一步一步剖析Dictionary实现原理
本文是对c#中Dictionary内部实现原理进行简单的剖析.如有表述错误,欢迎指正. 主要对照源码来解析,目前对照源码的版本是.Net Framwork 4.8,源码地址. 1. 关键的字段和Ent ...
- Redis开发与运维:linux安装
Linux 安装 我的系统是inux 系统,官网下载 https://redis.io/download redis-5.0.5.tar.gz 解压: 编译安装: 官网和文档说得已经很清楚了,现在就执 ...
- servlet中的forward()和redirect()
从地址栏显示来说 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器 浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏 ...
- LeetCode_232-Implement Queue using Stacks
题意是使用栈实现队列:队列是先进先出,后进后出. class MyQueue { public: /** Initialize your data structure here. */ MyQueue ...
- [转] Java 无界阻塞队列 DelayQueue 入门实战
原文出处:http://cmsblogs.com/ 『chenssy』 DelayQueue是一个支持延时获取元素的无界阻塞队列.里面的元素全部都是"可延期"的元素,列头的元素是最 ...
- Hyper-V 下linux虚拟机静态IP上网配置的两种方式(1)
工作需要,搭建linux环境,网上搜了两种Hyper-V配置linux静态IP及上网的方式,记录一下,方便查阅,如下是桥接方式的配置: 本实例所用的各项资源说明,系统是windows10企业版64bi ...
- JavaScript ES6函数式编程(一):闭包与高阶函数
函数式编程的历史 函数的第一原则是要小,第二原则则是要更小 -- ROBERT C. MARTIN 解释一下上面那句话,就是我们常说的一个函数只做一件事,比如:将字符串首字母和尾字母都改成大写,我们此 ...
- MYSQL事件隔离级别以及复读,幻读,脏读的理解
一.mysql事件隔离级别 1未提交读(READUNCOMMITTED) 另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据(脏读)( 隔离级别最低,并发性能高 ) 2 ...
- 【RT-Thread】线程的基本知识
什么是线程? 人们在生活中处理复杂问题时,惯用的方法就是分而治之,即把一个大问题分解成多个相对简单.比较容易解决的小问题,小问题逐个被解决了,大问题也就随之解决了.同样,在设计一个较为复杂的应用程序时 ...