题: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. Banner信息收集和美杜莎使用(9.26 第十二天)

    Banner信息收集 Banner信息,欢迎语,在banner信息中可以得到软件开发商.软件名称.版本.服务类型等信息,通过这些信息可以使用某些工具直接去使用相对应的exp去攻击 前提条件:需要和目标 ...

  2. js 琐碎

    1.setTimeout() .setInterval() setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式.(即n毫秒后执行一次) setTimeout(code,n) set ...

  3. POJ 2481:Cows 树状数组

    Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 14906   Accepted: 4941 Description ...

  4. C语言-存储类&作用域&生命周期&链接属性

    1.概念解析(1)存储类 a.存储类就是存储类型,也就是描述C语言变量在何种地方存储. b.内存有多种管理办法:栈.堆.数据段.bss段..text段......一个变量的存储类属性就是描述这个变量存 ...

  5. CSS - input 美化

    input{ padding: 20px; width: 100%; height: 5vh; margin-bottom: 2vh; border-radius: 10vw; border: 0; ...

  6. SpringAOP切入点的表达式

    1. 常用的切入点表达式分为:  (1)按类型匹配:within 关键字 (2)按函数匹配:execution (3)按bean的id匹配:bean 2.按类匹配的写法 匹配到具体的类:<aop ...

  7. JSP页面获取其他页面传递的参数

    jstl表达式获取方式: ${param.pid} el表达式获取方式: ${requestScope.attr}  el表达式获取方式: ${attr} ---------------------- ...

  8. redis主要配置项

    目录 redisd配置 redis主要配置项 这里就列举两例示例,之后的实验会有详细的示例!! redisd配置 redis主要配置项 bind 0.0.0.0 #监听地址,可以用空格隔开后多个监听I ...

  9. JMP CALL RET

    一.JMP指令(修改EIP的值)(第一个修改EIP的指令) 三种方法 :JMP 立即数 JMP  寄存器 JMP  内存 EIP 之前介绍过,EIP存放的值就是cpu下一次要执行的地址 1.之前学过要 ...

  10. C#窗体与SQL数据库的连接

    /*通过C#winform程序访问数据库数据 用到的命名空间和变量类型: using System.Data.SqlClient; SqlConnection:数据库连接类 SqlCommand:数据 ...