HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=2243
题意:
给出m个模式串,求长度不超过n的且至少包含一个模式串的字符串个数。
思路:
如果做过poj2778的话,那么这题相对来说就会容易一些。
如果直接去计算的话,情况很复杂,和poj2778一样,我们先求出不包含模式串的个数,最后只需要相减就可以。
因为这道题目长度只要不超过n就可以,所以在构造矩阵的时候需要多加一列,该列值每行全设为1(这样最后一列的值就是对上一个矩阵每一行的和,完美计算了了各种长度的个数之和)。最后得到的值res-1就是不包含的情况个数(减去1是因为一开始的时候多算了1)。
接下来计算一下所有情况的个数,$f(n)=1+26^1+26^2+...+26^n$,可以得出$f(n)=26*f(n-1)+1$,于是这就能构造出一个矩阵了,最后得到的res-1就是所有的情况个数。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m, num;
char s[]; struct Trie
{
int son[];
int cnt;
int fail;
}t[]; struct Matrix
{
unsigned long long mat[][], n;
Matrix(){}
Matrix(int _n)
{
n=_n;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
mat[i][j]=;
}
Matrix operator*(const Matrix& b) const
{
Matrix c=Matrix(n);
for(int i=;i<n;i++)
{
for(int j=;j<n;j++)
{
for(int k=;k<n;k++)
{
c.mat[i][j]+=mat[i][k]*b.mat[k][j];
}
}
}
return c;
}
}; void init(int x)
{
t[x].fail=;
t[x].cnt=;
memset(t[x].son,,sizeof(t[x].son));
} void trie(char *s)
{
int n=strlen(s);
int x=;
for(int i=;i<n;i++)
{
int c=s[i]-'a'+;
if(!t[x].son[c])
{
num++;
init(num);
t[x].son[c]=num;
}
x=t[x].son[c];
}
t[x].cnt=;
} void buildAC()
{
queue<int> Q;
for(int i=;i<=;i++) if(t[].son[i]) Q.push(t[].son[i]);
while(!Q.empty())
{
int x=Q.front(); Q.pop();
int fail=t[x].fail;
for(int i=;i<=;i++)
{ int y=t[x].son[i];
if(y)
{
t[y].fail=t[fail].son[i];
t[y].cnt|=t[t[fail].son[i]].cnt; //这儿很重要,这个标记需要传递
Q.push(y);
}
else t[x].son[i]=t[fail].son[i];
}
}
} Matrix getMatrix()
{
Matrix c=Matrix(num+);
for(int i=;i<=num;i++)
{
for(int j=;j<=;j++)
{
if(t[t[i].son[j]].cnt==) c.mat[i][t[i].son[j]]++;
}
}
for(int i=; i<num+; i++) c.mat[i][num+]=;
return c;
} Matrix q_pow(Matrix base, int n)
{
Matrix ans=Matrix(base.n);
for(int i=;i<ans.n;i++) ans.mat[i][i]=;
while(n)
{
if(n&) ans=ans*base;
base=base*base;
n>>=;
}
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&m,&n))
{
init();
num=;
for(int i=;i<=m;i++)
{
scanf("%s",s);
trie(s);
}
buildAC();
Matrix c=getMatrix();
c = q_pow(c,n);
unsigned long long res = ;
for(int i=;i<c.n;i++) res+=c.mat[][i];
res--;
c=Matrix();
c.mat[][]=;
c.mat[][]=c.mat[][]=;
c=q_pow(c,n);
unsigned long long ans=c.mat[][]+c.mat[][];
ans--;
ans-=res;
cout<<ans<<endl;
}
return ;
}
HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)的更多相关文章
- hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+DP+快速幂)
题目链接 错的上头了... 这题是DNA的加强版,26^1 +26^2... - A^1-A^2... 先去学了矩阵的等比数列求和,学的是第二种方法,扩大矩阵的方法.剩下就是各种模板,各种套. #in ...
- hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和
题目链接 题意 给定\(N\)个词根,每个长度不超过\(5\). 问长度不超过\(L(L\lt 2^{31})\),只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个? 思路 状态(AC自动 ...
- [hdu2243]考研路茫茫——单词情结(AC自动机+矩阵快速幂)
题意:长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个. 解题关键:利用补集转化的思想,先求一个词根也不包含的单词个数,然后用总的减去即可.长度不超过L需要用矩阵维数增加一倍 ...
- hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)
题目链接:hdu_2243_考研路茫茫——单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 2243 考研路茫茫——单词情结
考研路茫茫——单词情结 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID ...
- HDU 2243 考研路茫茫——单词情结 求长度小于等于L的通路总数的方法
http://acm.hdu.edu.cn/showproblem.php?pid=2243 这是一题AC自动机 + 矩阵快速幂的题目, 首先知道总答案应该是26^1 + 26^2 + 26^3 .. ...
- HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化
题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memor ...
随机推荐
- 前端写一个月的原生 Android 是如何一种体验?
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/j01G58UC80251/article/details/79017706 一个前端程序猿的一个月原 ...
- CentOS工作内容(四)主机禁ping
CentOS工作内容(四)主机禁ping 用到的快捷键 tab 自动补齐(有不知道的吗) ctrl+a 移动到当前行的开头(a ahead) ctrl+u 删除(剪切)此处至开始所有内容 vim 末行 ...
- 上传指定url文件到阿里云oss
好处是不用下载到本地,也不用删除本地文件.省事! 先下载阿里云官方代码 https://github.com/aliyun/aliyun-oss-csharp-sdk 引用其中的 aliyun-os ...
- SparkSQL UDF使用方法与原理详解
UDF是SQL中很常见的功能,但在Spark-1.6及之前的版本,只能创建临时UDF,不支持创建持久化的UDF,除非修改Spark源码.从Spark-2.0开始,SparkSQL终于支持持久化的UDF ...
- NLP语料库
文本语料库是一个大型结构化文本的集合 NLTK包含了许多语料库: (1)古滕堡语料库 (2)网络和聊天文本 (3)布朗语料库 (4)路透社语料库 (5)就职演讲语料库 (6)标注文本语料库 词汇列表 ...
- ambari集成impala
1.查看hdp版本,可在ambari-agent节点上查看 VERSION=`hdp-select status hadoop-client | sed 's/hadoop-client - \([0 ...
- 有意思的JSON.parse()、JSON.stringify()
前言 现在JSON格式在web开发中非常重要,特别是在使用ajax开发项目的过程中,经常需要将后端响应的JSON格式的字符串返回到前端,前端解析成JS对象值(JSON 对象),再对页面进行渲染. 在数 ...
- uva11354 LCA+最小生成树+dp
源自大白书 题意 有n座城市通过m条双向道路相连,每条道路都有一个危险系数.你的任务是回答若干个询问,每个询问包含一个起点s和一个终点t,要求找到一条从s到t的路,使得途径所有的边的大最大危险系数最小 ...
- Assets.xcassets 应用
1.应用 Assets.xcassets :用来存放图像资源文件 给项目添加 AppIcon 时图标要用 png 格式的,不要用其他格式.当是其它图片格式时 ,不要仅仅修改其后缀名,若仅仅修改后缀名, ...
- SQL: 左连接,右连接,内连接,左外连接,右外连接,完全连接
例子: ---------------------- --------------------------- a表 id name b表 id job parent_id 1 张三 ...