题:http://acm.hdu.edu.cn/showproblem.php?pid=2243

题意:给出m个模式串,求长度小于n的且存在模式串的字符串数有多少个(a~z)

分析:我们反着来,用总的减去不包含的,总的很容易想到,每个位置都有26个选择,所以是Σ1n26i  不包含的 这里  有解决恰好长度为n的方法,但这里要小于等于n的全部;

   其实解决方法类似,将上述的解题方法中的方案矩阵设为A,那么我们构造如下矩阵(含解释)

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
const int N=1e3+;
const int maxn=;
struct ac{
int trie[N][maxn],fail[N];
ll A[N][N],T[N][N],tmp[N][N];
bool end[N];
int root,tot;
int newnode(){
for(int i=;i<maxn;i++)
trie[tot][i]=-;
end[tot++]=;
return tot-;
}
void init(){
memset(A,,sizeof(A));
memset(end,false,sizeof(end));
tot=;
root=newnode();
}
void insert(char buf[]){
int now=root,len=strlen(buf);
for(int i=;i<len;i++){
if(trie[now][buf[i]-'a']==-)
trie[now][buf[i]-'a']=newnode();
now=trie[now][buf[i]-'a'];
}
end[now]=true;
}
void getfail(){
queue<int>que;
while(!que.empty())
que.pop();
fail[root]=root;
for(int i=;i<maxn;i++){
if(trie[root][i]==-)
trie[root][i]=root;
else{
fail[trie[root][i]]=root;
que.push(trie[root][i]);
}
}
while(!que.empty()){
int now=que.front();
que.pop();
if(end[fail[now]])
end[now]=true;
for(int i=;i<maxn;i++){
if(trie[now][i]!=-){
fail[trie[now][i]]=trie[fail[now]][i];
que.push(trie[now][i]);
}
else
trie[now][i]=trie[fail[now]][i];
}
}
}
void getA(){
for(int i=;i<tot;i++)
for(int j=;j<maxn;j++)
if(!end[i]&&!end[trie[i][j]]){
A[i][trie[i][j]]++;
} ///构造所说的前缀和的矩阵
for(int i=;i<=tot;i++)
A[i][tot]=;
}
void mul(ll a[][N],ll b[][N],int len){
for(int i=;i<len;i++)
for(int j=;j<len;j++){
tmp[i][j]=;
for(int k=;k<len;k++)
tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j]);
}
for(int i=;i<len;i++)
for(int j=;j<len;j++)
a[i][j]=tmp[i][j];
}
void solve(ll n,ll len){///这里的俩个参量要是换成int会t。。。。
memset(T,,sizeof(T));
for(int i=;i<len;i++)
T[i][i]=;
while(n){
if(n&)
mul(T,A,len);
mul(A,A,len);
n>>=;
} }
}AC;
char s[];
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
AC.init();
for(int i=;i<=n;i++){
scanf("%s",s);
AC.insert(s);
}
AC.getfail();
// cout<<AC.tot<<"!!"<<endl;
AC.getA();
AC.solve(m,AC.tot+);///不包含的 ll ans=;
for(int i=;i<=AC.tot;i++)
ans=(ans+AC.T[][i]);
///全部的
AC.A[][]=,AC.A[][]=;
AC.A[][]=, AC.A[][]=;
AC.solve(m+,);
///全部-不包含的
printf("%I64u\n",AC.T[][]-ans);
}
return ;
}

poj2243前一道题升级(思维构造+ac自动机)的更多相关文章

  1. AC自动机基础知识讲解

    AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...

  2. Aho-Corasick automaton(AC自动机)解析及其在算法竞赛中的典型应用举例

    摘要: 本文主要讲述了AC自动机的基本思想和实现原理,如何构造AC自动机,着重讲解AC自动机在算法竞赛中的一些典型应用. 什么是AC自动机? 如何构造一个AC自动机? AC自动机在算法竞赛中的典型应用 ...

  3. 【AC自动机】【字符串】【字典树】AC自动机 学习笔记

    blog:www.wjyyy.top     AC自动机是一种毒瘤的方便的多模式串匹配算法.基于字典树,用到了类似KMP的思维.     AC自动机与KMP不同的是,AC自动机可以同时匹配多个模式串, ...

  4. HDU4758 Walk Through Squares(AC自动机+状压DP)

    题目大概说有个n×m的格子,有两种走法,每种走法都是一个包含D或R的序列,D表示向下走R表示向右走.问从左上角走到右下角的走法有多少种走法包含那两种走法. D要走n次,R要走m次,容易想到用AC自动机 ...

  5. HDU 2825 AC自动机+DP

    题意:一个密码,长度为 n,然后有m个magic words,这个密码至少由k个magic words组成. 问这个密码可能出现的总数. 思路:首先构造AC自动机,由于m很小,才10 ,我们可以使用二 ...

  6. 多模字符串匹配算法之AC自动机—原理与实现

    简介: 本文是博主自身对AC自动机的原理的一些理解和看法,主要以举例的方式讲解,同时又配以相应的图片.代码实现部分也予以明确的注释,希望给大家不一样的感受.AC自动机主要用于多模式字符串的匹配,本质上 ...

  7. CodeForces - 710F:String Set Queries (二进制分组 处理 在线AC自动机)

    ou should process m queries over a set D of strings. Each query is one of three kinds: Add a string ...

  8. 【bzoj1030】: [JSOI2007]文本生成器 字符串-AC自动机-DP

    [bzoj1030]: [JSOI2007]文本生成器 首先把匹配任意一个的个数的问题转化为总个数-没有一个匹配的个数 先构造AC自动机,然后枚举每一位的字母以及在自动机上的位置 f[i][j]为第i ...

  9. 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)

    已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...

随机推荐

  1. 047-PHP数字前面补零,固定位数补0

    <?php #PHP 数字前面补零 固定位数补0 $num=128; $num=str_pad($num,8,"0",STR_PAD_LEFT); echo $num; // ...

  2. 158-PHP strstr函数输出第一次出现字符串的位置到字符串结尾的所有字符串

    <?php $str='PHP is a very good programming language!'; //定义一个字符串 echo '第一次出现字母l的位置到字符串结尾的所有字符串'.s ...

  3. 干货分享:如何搞定Essay Paragraph部分?

    想要写出一篇高质量的留学生作业,首先要从写好段落(paragraph)开始.那么今天就随小编一起来看看,如何写好Paragraph部分? 段落:在英文中我们俗称为paragraph,而一篇英文文章通常 ...

  4. 实验吧-杂项-你没有见过的加密!(php srand()和rand()函数)

    什么垃圾东西,弄半天,Windows上运行乱码,linux上7.3的php运行也是乱码(气死). 下载文件,查看内容 <?php function encrypt($str) { $crypte ...

  5. webpack散记--Typescript

    Typescript 1.js的超集 官网:typescriptlang.org/tslang.cn 来自:微软 安装:官方的  npm i typescript ts-loader --save-d ...

  6. java的JDBC的事务学习

    https://www.cnblogs.com/chy18883701161/p/11372089.html

  7. vagrant 学习笔记

    之所以学习他是因为最近换了电脑 又要重新搭环境  很烦躁然后就有了然后 1.先安装 virtualbox2.安装 vagrant3.安装xshell4.重启5.下载系统镜像 (可以去vagrant官网 ...

  8. Swift 3必看:从使用场景了解GCD新API

    https://www.jianshu.com/p/fc78dab5736f 2016.10.06 21:59* 在学习Swift 3的过程中整理了一些笔记,如果想看其他相关文章可前往<Swif ...

  9. 代码神器:拒绝重复编码,这款IDEA插件了解一下.....

    作者:HeloWxl www.jianshu.com/p/e4192d7c6844 Easycode是idea的一个插件,可以直接对数据的表生成entity.controller.service.da ...

  10. PAT 2014 秋

    A 1084 Broken Keyboard 注意大小写即可. #include <cstdio> #include <iostream> #include <algor ...