【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不太好 ...
随机推荐
- 最清晰的RESTFUL理解
Restful理解 API(Application Programming Interface),顾名思义:是一组编程接口规范,客户端与服务端通过请求响应进行数据通信.REST(Representat ...
- Vue三步完成跨域请求
三步完成跨域请求 ①main.js中: Vue.prototype.HOME = '/api'; ② config/index.js中: module.exports = { dev: { // Pa ...
- C#使用GUID作为随机数种子
使用C#默认的Random无参构造的next生成的随机数,在快速生成随机数的时候,会出现大批量的重复.使用guid作为随机数种子,效果会好很多 Guid temp = Guid.NewGuid(); ...
- php实现商城秒杀
这一次总结和分享用Redis实现分布式锁来完成电商的秒杀功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意思,若有误请谅解 ...
- MYSQL SQL语句 之 select
select语句在数据库操作中是操作频率最高的语句,使用方式也是多种多样,它的基本功能是:从表中选取数据,结果存储在一个结果集中.可以联合where,and,or,Order By,distinct, ...
- Mariadb 基于Mycat实现读写分离
环境:Mariadb主:192.168.200.129 Mariadb从:192.168.200.114 Mycat :192.168.200.112 (1) 安装jdk,先查看本机是 ...
- 1046 Shortest Distance (20 分)
1046 Shortest Distance (20 分) The task is really simple: given N exits on a highway which forms a si ...
- 秘制CSP模板
不定期更细中...... 声明1:由于js的问题导致VIEW CODE按钮只能点"I"附近才能展开代码 声明2:为了排版的美观,所有的解释以及需要留意的地方我都放在代码中了 声明3 ...
- Vue躬行记(3)——样式和表单
Vue对DOM元素的class和style两个特性做了专门的增强,即对CSS类和内联样式做了一层封装,通过v-bind指令来处理它们,而接收的表达式既可以是简单的字符串.对象或数组,也可以是复杂的计算 ...
- thinkphp5底层基类封装、内部类函数
记录下thinkphp5自定义底层基类.内部类函数使用笔记 大部分笔记来自tp手册. 底层常用代码的封装 在控制器中基类的起着至关重要的作用,整个项目的代码安全,复杂程度,易读性都要看你项目的基类架构 ...