题目大意:

    给出一些匹配串,要造一个长度不超过L的字符串,每个匹配串有自己的价值,匹配串每次出现在字符串里都会贡献一次价值...要求可能得到的最大价值。

    匹配串总长不超200,L<=10^14,时限6s

  典型的倍增floyd...看数据范围大概就知道是什么东西了= =

  暴力写法的话..建个AC自动机,每个节点的价值,就是结束节点在它的fail链上的匹配串的价值总和。。 然后在上面暴力DP。f[i][j]表示从i节点开始,往后走j步能得到的最大价值。

  这个形式和USACO那道“奶牛接力跑‘一模一样。。。

  f[i][j][k]表示从i节点开始,走2^j步,到达k的最大价值。fa[i][j][k]:从k节点开始,走2^j步,能否到达i。

  f[i][j][k]=max{ f[i][j-1][k1]+f[k1][j-1][k] },( fa[k1][j-1][i]和fa[k][j-1][k1]为true

  求出f后,就和快速幂的姿势一样把L拆成若干个二的次幂之和,然后把对应的各个f数组并起来(记为g)。

  最后的答案就是max{ g[0][i] },(i为自动机上的节点。

  时间复杂度O(n^3*logL)..CF测评姬挺快的。。只跑了1200+ms。。

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<bitset>
#define ll long long
#define ull unsigned long long
#define d double
using namespace std;
const int maxn=;
const ll inf=(1ll<<)-1ll;
int ch[maxn][],next[maxn][],tot;
int dl[maxn],fail[maxn],val[maxn],v[maxn];
ll f[maxn][][maxn],g[maxn][][maxn];
bitset<maxn>fa[maxn][];
char s[maxn]; int i,j,k,n,m,now,pre;
ll L;
bool first=; int ra,fh;char rx;
inline int read(){
rx=getchar(),ra=,fh=;
while(rx!='-'&&(rx<''||rx>''))rx=getchar();
if(rx=='-')fh=-,rx=getchar();
while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra*fh;
}
inline void upd(ll &a,ll b){if(a<b)a=b;} void trie(int n,int v){
int p=;
for(int i=;i<=n;i++){
s[i]-='a';
if(!ch[p][s[i]])ch[p][s[i]]=++tot,p=tot;
else p=ch[p][s[i]];
}
val[p]+=v;//printf(" ggpos:%d\n",p);
}
void getfail(){
int l=,r=,i,now,j,p;dl[]=;
while(l<r){
now=dl[++l];
for(i=;i<;i++)if(ch[now][i]){
j=ch[now][i],dl[++r]=j,next[now][i]=j;
for(p=fail[now];p&&!ch[p][i];p=fail[p]);
if(!now)fail[j]=;else fail[j]=ch[p][i];
val[j]+=val[fail[j]];//printf(" %d - - - ->%d val:%d\n",j,fail[j],val[j]);
}else{
for(p=fail[now];p&&!ch[p][i];p=fail[p]);
next[now][i]=ch[p][i];
}
}
} inline void run_fa(int j){
int i,k1;//printf("j:%d\n",j);
for(i=;i<=tot;i++)for(k1=;k1<=tot;k1++)
if(fa[i][j-][k1])fa[i][j]|=fa[k1][j-];
// for(i=0;i<=tot;i++)for(k1=0;k1<=tot;k1++)if(fa[i][j][k1])printf(" %d->%d\n",k1,i);
}
inline void run_f(int j){
int i,k;register int k1;//printf("j:%d\n",j);
for(i=;i<=tot;i++)for(k=;k<=tot;k++)if(fa[k][j][i]){
for(k1=;k1<=tot;k1++)if(fa[k1][j-][i]&&fa[k][j-][k1])
upd(f[i][j][k],f[i][j-][k1]+f[k1][j-][k]);//,printf(" %d-->%d-->%d\n",i,k1,k);
}else f[i][j][k]=-inf;
}
inline void run_merge(int j){
int i,k;register int k1;
if(first){
first=;
for(i=;i<=tot;i++)for(k=;k<=tot;k++)g[i][now][k]=f[i][j-][k];
return;
}
for(i=;i<=tot;i++)for(k=;k<=tot;k++)
for(g[i][now][k]=-inf,k1=;k1<=tot;k1++)if(fa[k][j-][k1])
upd(g[i][now][k],g[i][pre][k1]+f[k1][j-][k]);
} int main(){
n=read(),scanf("%I64d",&L);
for(i=;i<=n;i++)v[i]=read();
for(i=;i<=n;i++)scanf("%s",s+),trie(strlen(s+),v[i]);
getfail(); int a=;
for(i=;i<=tot;i++)for(k=;k<=tot;k++)f[i][][k]=-inf;
for(i=;i<=tot;i++)for(j=;j<;j++)fa[next[i][j]][][i]=,f[i][][next[i][j]]=val[next[i][j]]; // for(i=0;i<=tot;i++)for(int k1=0;k1<=tot;k1++)if(fa[i][0][k1])printf(" %d->%d\n",k1,i); now=,pre=;
while(L){
a++;
if(L&)run_merge(a),swap(now,pre);
L>>=;
if(!L)break;
run_fa(a),run_f(a);
}
ll ans=;
for(i=;i<=tot;i++)upd(ans,g[][pre][i]);
printf("%I64d\n",ans);
}

比赛的时候这道题肝了整整1h。。。最后1min才过的样例..竟然就过掉了

[Codeforces 696D] Legen...的更多相关文章

  1. Codeforces 696D Legen...(AC自动机 + 矩阵快速幂)

    题目大概说给几个字符串,每个字符串都有一个开心值,一个串如果包含一次这些字符串就加上对应的开心值,问长度n的串开心值最多可以是多少. POJ2778..复习下..太弱了都快不会做了.. 这个矩阵的乘法 ...

  2. 【Codeforces 696D】Legen...

    Codeforces 696 D 题意:给\(n\)个串,每个串有一个权值\(a_i\),现在要构造一个长度为\(l\leq 10^{14}\)的串,如果其中包含了第\(i\)个串,则会得到\(a_i ...

  3. CodeForces - 697F:Legen... (AC自动机+矩阵)

    Barney was hanging out with Nora for a while and now he thinks he may have feelings for her. Barney ...

  4. Codeforces 696 D. Legen...

    Description 每个字符串有些价值,问生成长度为 \(l\) 的字符串最多能获得多少价值,总字符数不超过 \(200\), \(l\leqslant 10^{14}\) . Sol AC自动机 ...

  5. Codeforces Round #362(Div1) D Legen...(AC自动机+矩阵快速幂)

    题目大意: 给定一些开心串,每个串有一个开心值,构造一个串,每包含一次开心串就会获得一个开心值,求最大获得多少开心值. 题解: 首先先建立AC自动机.(建立fail指针的时候,对val要进行累加) 然 ...

  6. codeforces泛做..

    前面说点什么.. 为了完成日常积累,傻逼呵呵的我决定来一发codeforces 挑水题 泛做.. 嗯对,就是泛做.. 主要就是把codeforces Div.1的ABCD都尝试一下吧0.0.. 挖坑0 ...

  7. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  8. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  9. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

随机推荐

  1. ABP-Module

    [TOC] 什么是Module? Module就是模块化的设计思想.开发人员可以将自定义的功能以模块的形式集成到项目中.具体的功能也可以设计成一个单独的模块 AbpModule AbpModule是所 ...

  2. ABP .Net Core 部署到IIS 问题汇总

    在ABP官网创建一个.Net Core项目编译完成 1. 发布网站 2. IIS新建站点 目录指向发布的目录 3.安装WindowsHosting IIS安装服务器上安装DotNetCore.X.X. ...

  3. C语言_第二讲_规范以及常用数据类型

    一丶编码规范基本数据类型 编码规范 任何程序员,都应该有良好的的编码习惯,便于以后的代码可读性和维护 常见了编码规范有 匈牙利命名法 驼峰式大小写 匈牙利命名法: 是电脑程序设计中的一种变量命名规则, ...

  4. echarts异步数据加载(在下拉框选择事件中异步更新数据)

    接触echarts 大半年了,从不会到熟练也做过不少的图表,隔了一段时间没使用这玩意,好多东西真心容易忘了.在接触echarts这期间也没有总结什么东西,今天我就来总结一下如何在echart中异步加载 ...

  5. ArcGIS 网络分析[2.3] 最近设施点

    什么是最近设施点? 仍然举一个生动形象例子说明. 我在大街的某一个点儿上,我急需上厕所,问:我3分钟内能到的最近的厕所在哪? 这就是最近设施点分析(ClosestFacility)--给定搜索半径,基 ...

  6. canvas学习api

    1.canvas.getContext():获取渲染上下文和绘画功能: 一.绘制矩形 2.ctx.fillRect(x,y,width,height):绘制矩形: 3.ctx.strokeRect(x ...

  7. [知了堂学习笔记]_用JS制作《飞机大作战》游戏_第2讲(四大界面之间的跳转与玩家飞机的移动)

    一.通过点击按钮事件,实现四大界面之间的跳转: (一)跳转的思路: 1.打开软件,只显示登录界面(隐藏游戏界面.暂停界面.玩家死亡界面) 2.点击微信登录(QQ登录)跳转到游戏界面,隐藏登录界面 3. ...

  8. Python:监控ASM剩余空间

    #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Jipu FANG' version = 0.1 import cx_Oracle ...

  9. UTC 通用格式时间 转换为 时间戳,并格式化为2017-01-01 12:00:00

    在使用阿里云oss获取文件列表是,发现时间格式是这样的 2016-09-20T13:45:04.000Z (尼玛,是什么鬼), 经过度娘的解答,发现这就是传说中的 UTC通用格式时间 问题来了,怎么转 ...

  10. day9集合以及这段时间的总结 未完待续

    随笔: # 可变类型:# 列表(可以存放多个值,可以按索引取值,是有序的),# 字典(字典里面是KEY:VALUE类型,key必须是不可变类型,不能按索引取值 因为它们是无序的,按KEY取值),# 集 ...