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. android activity and fragment活动周期

    1.状态 /* 每个活动一共有四种状态 *:1.运行状态,就是栈顶的那个 * 2.暂停状态:就是不处于栈顶,但是依然可见,比如对话框下面的界面 * 3.停止状态:不处于栈顶,并且不可见 * 4.销毁状 ...

  2. 简述ASP.NET的页面运行机制

    在深入学习ASP.NET之前,首先需要先了解一下ASP.NET的页面运行机制: 浏览以下内容需要对ASP.NET管道有一定的了解,附上很不错的几个链接: 选择HttpHandler还是HttpModu ...

  3. MVC中的传参并在View中获取

    首先action跳转的模式有如下: redirecttoaction("index");//一个参数时在本controller下,不传入参数. redirecttoaction(a ...

  4. Directed Graph Loop detection and if not have, path to print all path.

    这里总结针对一个并不一定所有点都连通的general directed graph, 去判断graph里面是否有loop存在, 收到启发是因为做了[LeetCode] 207 Course Sched ...

  5. Fuzzy and fun on Air Jordan 12 Doernbecher design

    Carissa Navarro keeps it warm, fuzzy and fun on her 2017 Air Jordan 12 Doernbecher design. Nike's 20 ...

  6. 7.7 Models -- Working with Records

    Modifying Attributes 1. 一旦一条record被加载,你可以开始改变它的属性.在Ember.js对象中属性的行为就像正常的属性.作出改变就像设置你想要改变的属性一样简单: var ...

  7. ACM 未解决的问题

    还没有搞定的ACM问题列表. google code jam Round1A Round1B Round1C Round2 Round3 Onsite Finals 百度之星 一.资格赛题目: dis ...

  8. label--input

    .form-group { margin-bottom: 15px; position: relative;}.control-label{ float: left; width: 15%; text ...

  9. ac1067

    这题说的是 有n个点在 圆上等分这个圆,然后 然后计算其中任意三个点能组成的锐角三角形的个数 首先这些点能组成的三角形的个数为 n*(n-1)*(n-2)/6  接下来计算不是锐角三角形的个数 固定任 ...

  10. 学号20155311 2016-2017-2 《Java程序设计》第9周学习总结

    学号 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 整合数据库 JDBC(Java DataBase Connectivity)即java数据库连接,是一种 ...