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自动机+矩阵快速幂)的更多相关文章

  1. hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...

  2. HDU 2243 考研路茫茫——单词情结(AC自动机+DP+快速幂)

    题目链接 错的上头了... 这题是DNA的加强版,26^1 +26^2... - A^1-A^2... 先去学了矩阵的等比数列求和,学的是第二种方法,扩大矩阵的方法.剩下就是各种模板,各种套. #in ...

  3. hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和

    题目链接 题意 给定\(N\)个词根,每个长度不超过\(5\). 问长度不超过\(L(L\lt 2^{31})\),只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个? 思路 状态(AC自动 ...

  4. [hdu2243]考研路茫茫——单词情结(AC自动机+矩阵快速幂)

    题意:长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个. 解题关键:利用补集转化的思想,先求一个词根也不包含的单词个数,然后用总的减去即可.长度不超过L需要用矩阵维数增加一倍 ...

  5. hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)

    题目链接:hdu_2243_考研路茫茫——单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...

  7. HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. HDU 2243 考研路茫茫——单词情结

    考研路茫茫——单词情结 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID ...

  9. HDU 2243 考研路茫茫——单词情结 求长度小于等于L的通路总数的方法

    http://acm.hdu.edu.cn/showproblem.php?pid=2243 这是一题AC自动机 + 矩阵快速幂的题目, 首先知道总答案应该是26^1 + 26^2 + 26^3 .. ...

  10. HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化

    题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memor ...

随机推荐

  1. iOS开发-url包括中文报错解决的方法

    常常, 我们用通过这个方案调用API. NSString* urlString = [NSString stringWithFormat:@"http://api.douban.com/v2 ...

  2. APICloud-端JS库功能API文档(1)

    框架简介: 框架基于APICloud官网端API进行扩展和封装,框架完全采用面向对象编程形式,里面包含APP所使用的常用js功能:js类的自定义(类,构造方法,静态方法,继承...),常用工具函数(验 ...

  3. this与$scope

    最近在Angular项目中遇到关于controller内使用$scope&this 暴露数据的问题,下面来分析一下: "controller as" 是Angular在1. ...

  4. weka数据挖掘拾遗(二)---- 特征选择(IG、chi-square)

    一.说明 IG是information gain 的缩写,中文名称是信息增益,是选择特征的一个很有效的方法(特别是在使用svm分类时).这里不做详细介绍,有兴趣的可以googling一下. chi-s ...

  5. java实现Comparable接口和Comparator接口,并重写compareTo方法和compare方法

    原文地址https://segmentfault.com/a/1190000005738975 实体类:java.lang.Comparable(接口) + comareTo(重写方法),业务排序类 ...

  6. VUE路由去除#问题

    最近自己在写一个vue的小型管理系统,在浏览器中看到的路由都是带有#的,很是不好看.为了解决此问题,大家一般都会想到:mode: 'history'.可是在开发阶段没有问题,但是一旦build打包后, ...

  7. 4:7 Struts实现Ajax

    不使用插件: 返回数据: 使用插件: Action里面直接给User赋值,然后在前台拿值. type="json":表示返回json对象: root:表示作为跟对象 include ...

  8. KM算法模板

    大白书P248有证明,此处贴出两种复杂度的方案, n^4 大白书P350 n^3 #include <algorithm> #include <string.h> #inclu ...

  9. Asp.net MVC 通过自定义ControllerFactory实现构造器注入

    一.重写ControllerFactory的GetControllerInstance ControllerFactory是asp.net中用于在运行时构造Controller的工厂 ,默认使用的工厂 ...

  10. python socket编程函数介绍

    网上看到一个socket中常用函数的介绍,记录一下 https://blog.csdn.net/rebelqsp/article/details/22109925