什么鬼?,C++ AC, G++ 疯狂RE。。看题目就知道是递推的方法,但是肯定不能dp,看n可以达到20亿,自然想到用矩阵的乘法来递推。
题意
给你一些字符串代表有病毒的字符串,现在给你一个数字N,让你求长度为N且不包含病毒的字符串的数目。
思路
我们首先需要构建一个矩阵,问题是矩阵的元素代表什么,我们用矩阵的元素代表从一个点转移到另一个点的路线数目,那么矩阵的K次幂,就代表了从这个点经过K次路径(可以重复)到达另一个点的路线的数目。因此我们把构建出的矩阵求出K次幂,然后把第一行累加一下就可。因为起点一定是0点,而末尾的点可能是任意一个顶点。
问题是矩阵的构建了。我们需要用到AC自动机的fai指针了,我们首先把每个病毒字符串的末尾标记一下,然后我们在bfs中加上一句,如果该点的fail指针所指向的字母是被标记的,那么这个字母也要被标记。因为fail指针指向的是公共的后缀,如果这个后缀都被标记了,那么自然这个字符串中一定包含了病毒串。
1 | #include <set> |