Description

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

Sol

AC自动机 + 倍增Floyd.

用AC自动机统计到达每个节点会获得的权值.

然后在AC自动机从根节点开始找一条最长路,就用Floyd倍增就可以了...

发现自己AC自动机做Fail树的时候写错了,改了好久没改出来,最后发现不能直接将根扔进队列里...应该把根的所有子节点扔进去..

然后类似快速幂做就可以了.写矩阵的时候需要判断一下能否到达,我用 \(-1\) 来表示能否到达.

转移就是 \(C[i][j]=max\{C[i][j],A[i][k]+B[k][j]\},A[i][k]!=-1,B[k][j]!=-1\) .

Code

#include <bits/stdc++.h>
using namespace std; const int M = 205;
const int N = 20050;
typedef long long LL;
typedef vector< LL > Vec;
typedef vector< Vec > Mat; void F(Mat &A,int v=-1) {
int n=A.size();
for(int i=0;i<n;i++) for(int j=0;j<n;j++) A[i][j]=v;
}
Mat operator * (const Mat &A,const Mat &B) {
int n=A.size();Mat C(n,Vec(n));F(C);
for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++)
if(A[i][k]!=-1 && B[k][j]!=-1) C[i][j]=max(C[i][j],A[i][k]+B[k][j]);
return C;
}
Mat operator ^ (Mat A,LL b) {
int n=A.size();Mat r(n,Vec(n));
F(r);for(int i=0;i<n;i++) r[i][i]=0;
for(;b;b>>=1,A=A*A) if(b&1) r=r*A;
return r;
}
void Print(const Mat &A) {
int n=A.size();
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) cout<<A[i][j]<<" ";
cout<<endl;
}cout<<"---------------------"<<endl;
} struct AC_Auto {
int rt,cnt;
int f[N],ch[N][26],v[N]; int NewNode() { ++cnt;v[cnt]=f[cnt]=0,memset(ch[cnt],0,sizeof(ch[cnt]));return cnt; }
void init() { cnt=rt=f[rt]=v[rt]=0;memset(ch[rt],0,sizeof(ch[rt])); }
void insert(char *s,int val) {
int l=strlen(s),o=rt;
for(int i=0;i<l;i++) {
if(!ch[o][s[i]-'a']) ch[o][s[i]-'a']=NewNode();
o=ch[o][s[i]-'a'];
}v[o]+=val;
}
void getFail() {
queue< int > q;
for(int i=0;i<26;i++) if(ch[rt][i]) q.push(ch[rt][i]);
for(;!q.empty();) {
int x=q.front();q.pop();
for(int i=0;i<26;i++) {
if(!ch[x][i]) ch[x][i]=ch[f[x]][i];
else q.push(ch[x][i]),f[ch[x][i]]=ch[f[x]][i],v[ch[x][i]]+=v[f[ch[x][i]]];
}
}
// for(int i=0;i<=cnt;i++) cout<<i<<"-->"<<f[i]<<endl;
}
void Make(Mat &A) {
A.resize(cnt+1,Vec(cnt+1));
int n=A.size();F(A);
for(int i=0;i<n;i++) for(int j=0;j<26;j++) A[i][ch[i][j]]=v[ch[i][j]],A[i][ch[rt][j]]=v[ch[rt][j]];
}
}ac; LL n,l,ans;
LL a[N];
char s[N]; int main() {
// freopen("in.in","r",stdin); ios::sync_with_stdio(false);
ac.init(); cin>>n>>l;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>s,ac.insert(s,a[i]); ac.getFail();
Mat r;
ac.Make(r); // Print(r);
r=r^l; for(int i=0;i<(int)r.size();i++) ans=max(ans,r[0][i]); cout<<ans<<endl;
return 0;
}

  

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

  1. 【Codeforces 696D】Legen...

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

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

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

  3. Codeforces 696 C. PLEASE

    Description 三个杯子,一开始钥匙在中间,每次等概率的选择两边的两个,与中间的交换,问第 \(n\) 次选择中间的杯子是钥匙的概率是多少. \(n=\sum_{i=1}^{k} a_i,a_ ...

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

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

  5. [Codeforces 696D] Legen...

    题目大意: 给出一些匹配串,要造一个长度不超过L的字符串,每个匹配串有自己的价值,匹配串每次出现在字符串里都会贡献一次价值...要求可能得到的最大价值. 匹配串总长不超200,L<=10^14, ...

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

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

  7. Codeforces Round #696 (Div. 2) D. Cleaning (思维,前缀和)

    题意:有一堆石子,你每次可以选择相邻(就算两堆石子中间有很多空堆也不算)的两堆石子,使得两堆石子的个数同时\(-1\),你在刚开始的时候有一次交换相邻石子的机会,问你最后能否拿走所有石子. 题解:对于 ...

  8. Codeforces Round #696 (Div. 2) C. Array Destruction (贪心,multiset)

    题意:有\(n\)个数,首先任选一个正整数\(x\),然后在数组中找到两个和为\(x\)的数,然后去掉这两个数,\(x\)更新为两个数中较大的那个.问你最后时候能把所有数都去掉,如果能,输出最初的\( ...

  9. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

随机推荐

  1. 转: Protobuf 的 proto3 与 proto2 的区别

    Protobuf 的 proto3 与 proto2 的区别   On 2015-07-17 19:16:00 By Soli   Protobuf 的 proto3 与 proto2 的区别 这是一 ...

  2. canvas事件处理机制

    可以查看demo:http://sandbox.runjs.cn/show/hjb2hzzx(建议查看console查看点击后的改变) 具体原理是每次点击的时候去判断当前的鼠标坐标是属于哪一个路径下的 ...

  3. JSP九大内置组件

    request:用户端请求,此请求会包含来自get/post请求的参数 response:网页传回用户端的回应 pagecontext:网页上下文,也就是网页的属性 session:与请求有关的会话期 ...

  4. CSS3-3D制作案例分析实战

    一.前言 上一节,介绍了基础的CSS3 3D动画原理实现,也举了一个小小的例子来演示,但是有朋友跟我私信说想看看一些关于CSS3 3D的实例,所以在这里为了满足一下大家的需求,同时也为了以后能够更好的 ...

  5. 在CentOS 6.4 x86_32中使用Rhythmbox听MP3

    Linux中的Rhythmbox音乐播放器,是没有自带MP3音乐解码器的,所以必须得自行安装相应的音乐或视频解码器.好了,不废话…… # cd /tmp # wget http://dl.atrpms ...

  6. APIPA(Automatic Private IP Addressing,自动专用IP寻址)

    APIPA APIPA(Automatic Private IP Addressing,自动专用IP寻址),是一个DHCP故障转移机制.当DHCP服务器出故障时, APIPA在169.254.0.1到 ...

  7. QueryRunner类 的應用,以及ResultSetHandler 接口的实现类

    1 .该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式. ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql. ...

  8. 软件工程(FZU2015)助教总结

    本次构建之法-SE助教工作,和福州大学张老师协作,福大学生基本发挥出了一定水平,在此做个小结. 教师 张老师本身的SE教学经验足够丰富,对教学工作中的教师.助教.学生的角色定位清晰,整体节奏和安排合理 ...

  9. Xcode调试技巧(断点和重构)

    首先是最简单的普通断点有时候不知道是那个方法调用的崩溃的这个方法,传了个奇怪的值,打个断点就就可以在左侧工具栏里看到最近几个方法执行的循序,和那个方法调用的本方法,一般小问题在这里就可以解决啦~ 条件 ...

  10. os 模块

    __file__获取当前模块所在路径 一.os模块概述 Python os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的. 二.常用方法 1.os.name 输 ...