A. chino with string(ac自动机+floyd矩阵快速幂)
LINK
有mmm个字符串,每个字符串有一定的分值(可能为负数)
求出一个长nnn的字符串sss使得它的价值最大,你只需要输出这个最大的价值.
价值定义为∑i=1mcii∗pointi\sum\limits_{i=1}^m ci_i*point_ii=1∑mcii∗pointi
其中ciici_icii表示给定的第iii个字符串在sss中的出现次数,pointipoint_ipointi表示第iii个字符串的分值
对mmm个字符串建acacac自动机,每个节点预处理一个pointipoint_ipointi表示以这个节点结尾的所有串的分值和
当然这个pointpointpoint要在failfailfail树上推标记累加
容易想到定义f[i][j]f[i][j]f[i][j]表示长度为iii的字符串在jjj节点的最大分值
转移方程一目了然(满足qqq节点到jjj节点有边)
f[i][j]=maxq−>j{f[i−1][q]+pointj}f[i][j]=\max_{q->j}\{f[i-1][q]+point_j\}f[i][j]=q−>jmax{f[i−1][q]+pointj}
然而n<=109n<=10^9n<=109,一般来说可以使用矩阵快速幂,但这里是max\maxmax运算
初始矩阵为,长度是自动机上的节点个数,也就是相当于f[0][0],f[0][1]...f[0][id]f[0][0],f[0][1]...f[0][id]f[0][0],f[0][1]...f[0][id]的值
[0−inf⋯−inf]\begin{bmatrix} 0 & -inf & \cdots & -inf \\ \end{bmatrix} [0−inf⋯−inf]
转移矩阵为id∗idid*idid∗id的矩阵(下面用nnn表示ididid)
S=[x11x12⋯x1nx21x22⋯x2n⋮⋮⋱⋮xn1xn2⋯xnn]S= \begin{bmatrix} x_{11} & x_{12} & \cdots & x_{1n} \\ x_{21} & x_{22} & \cdots & x_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ x_{n1} & x_{n2} & \cdots\ & x_{nn} \\ \end{bmatrix} S=⎣⎢⎢⎢⎡x11x21⋮xn1x12x22⋮xn2⋯⋯⋱⋯ x1nx2n⋮xnn⎦⎥⎥⎥⎤
其中xi,jx_{i,j}xi,j表示,若iii节点到jjj节点有边,xi,j=mxjx_{i,j}=mx_jxi,j=mxj
若iii节点到jjj节点无边,xi,j=−infx_{i,j}=-infxi,j=−inf代表不能转移
这是一个外层max\maxmax运算,内层+++运算的矩阵乘法
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e6+10;
const ll inf = 1e17;
int n,m,mx;
struct rce
{ll m[201][201];rce(){ memset( m,-0x3f3f3f3f,sizeof m); }
};
rce operator * ( rce a, rce b )
{rce ans;for(int i=0;i<=mx;i++)for(int j=0;j<=mx;j++)for(int k=0;k<=mx;k++)ans.m[i][j] = max( ans.m[i][j],a.m[i][k]+b.m[k][j] );return ans;
}
int zi[maxn][30],fail[maxn],id = 1;
ll point[maxn];
char a[maxn];
void insert(char a[],int val)
{int len = strlen( a+1 ), now = 0;for(int i=1;i<=len;i++){if( !zi[now][a[i]-'a'] ) zi[now][a[i]-'a'] = ++id;now = zi[now][a[i]-'a'];}point[now] += val;
}
void make_fail()
{queue<int>q;for(int i=0;i<=25;i++)if( zi[0][i] ) q.push( zi[0][i] );while( !q.empty() ){int u = q.front(); q.pop();point[u] += point[fail[u]];for(int i=0;i<=25;i++){int v = zi[u][i];if( v )fail[v] = zi[fail[u]][i], q.push( v );else zi[u][i] = zi[fail[u]][i];}}
}
rce quick(rce x,int n)
{rce ans = x;for( ; n ; n>>=1,x=x*x )if( n&1 ) ans = ans*x;return ans;
}
int main()
{cin >> n >> m;for(int i=1;i<=m;i++){int val;scanf("%s%d",a+1,&val );insert( a,val );}make_fail(); mx = id;rce z;for(int i=0;i<=id;i++)for(int j=0;j<=25;j++){int v = zi[i][j];z.m[i][v] = point[v];}z = quick( z,n-1 ); ll ans = -inf;for(int i=0;i<=mx;i++) ans = max( ans,z.m[0][i] );cout << ans;
}
A. chino with string(ac自动机+floyd矩阵快速幂)相关推荐
- 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂
[题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...
- 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...
- [BJOI2017]魔法咒语(AC自动机+DP+矩阵快速幂)
文章目录 title solution code title solution 针对数据编程才是坠吊的!!! 观察数据,发现分隔数据的 L L L跨度过大,没有衔接--推测很有可能是分数据做法 ①:考 ...
- [BZOJ4861][Beijing2017]魔法咒语 AC自动机+动态规划+矩阵快速幂
对忌讳词语构建AC自动机 Fi,j F_{i,j}表示长度为 i i,匹配到AC自动机第jj位的合法串方案数 当状态数少的时候用矩阵转移 #include <bits/stdc++.h> ...
- BZOJ.4180.字符串计数(后缀自动机 二分 矩阵快速幂/倍增Floyd)
题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设 ...
- HDU5863 cjj's string game(DP + 矩阵快速幂)
题目 Source http://acm.split.hdu.edu.cn/showproblem.php?pid=5863 Description cjj has k kinds of charac ...
- POJ 2778 DNA Sequence (自动机DP+矩阵快速幂)
题意:给出m个致病DNA片段,求长为n且不含致病片段的DNA序列共有多少种. 数据范围:0 <= m <= 10,1 <= n <=2000000000 这题初看起来与上一题差 ...
- ZOJ 2317 Nice Patterns Strike Back(矩阵快速幂)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2317 题意:给你两种颜色,黑色和白色,填充n*m的方格,每个格子一种颜色, ...
- HDU - 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
题目链接:点击查看 题目大意:给出 n 个词根,现在要求出长度不大于 len 的单词中,有多少单词包含至少一个词根 题目分析:如果我们反过来想,也就是求出来总的单词数,然后减去不包含词根的单词数,剩下 ...
最新文章
- mysql忘记密码,如何重置密码
- PCB雕刻钻孔机制作
- [六省联考2017]分手是祝愿(期望+DP)
- Cannot find reference ‘PDFDocument‘ in ‘pdfparser.py‘
- 图论-欧拉图-欧拉回路-Euler-Fluery-Hierholzer-逐步插入回路法-DFS详解-并查集
- gitlab 迁移_无忌过招:手把手教你搭建自己的GitLab库
- mysql评论与回复一起查_mysql 查询所有评论以及回复
- UnityShader25:在Unity中实现泛光
- 10:Java人脸识别认证-Java API 实战
- 挑战程序设计竞赛 练习日记
- windows下创建本地局域网svnserver和gitserver
- f1c100s rootfs调试记录
- 后台管理系统架构成型
- 陈佼每周一蛋疼:“哼唱搜索”更像是个玩具
- 1000瓶药水和10只老鼠的问题及其扩展
- 安装Dreamweaver CS5遇到的问题
- windows 10 连接android手机助手,手把手教你Win10手机助手怎么用
- 《组织行为学》读后感_20170803
- 中国经典营销案例—农夫山泉
- CVE-2022-27778漏洞修复
热门文章
- os.system获取返回值 python3 cmd 获取返回值
- 数组、特殊矩阵、稀疏矩阵、广义表
- UVA 10526 - Intellectual Property (后缀数组)
- ssd nvme sata_NVMe SSD与传统SATA SSD
- 不要只怀揣梦想,而是要努力实现梦想!
- 芸赞通天下沈杨——怀揣梦想,不断努力
- [野火]EBF i.MX6ULL
- matlab最基础教程(二):变量类型与赋值
- github基础教程
- python中input是什么_Python中input函数的用法是什么?_后端开发