poj2243前一道题升级(思维构造+ac自动机)
题: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自动机)的更多相关文章
- AC自动机基础知识讲解
AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...
- Aho-Corasick automaton(AC自动机)解析及其在算法竞赛中的典型应用举例
摘要: 本文主要讲述了AC自动机的基本思想和实现原理,如何构造AC自动机,着重讲解AC自动机在算法竞赛中的一些典型应用. 什么是AC自动机? 如何构造一个AC自动机? AC自动机在算法竞赛中的典型应用 ...
- 【AC自动机】【字符串】【字典树】AC自动机 学习笔记
blog:www.wjyyy.top AC自动机是一种毒瘤的方便的多模式串匹配算法.基于字典树,用到了类似KMP的思维. AC自动机与KMP不同的是,AC自动机可以同时匹配多个模式串, ...
- HDU4758 Walk Through Squares(AC自动机+状压DP)
题目大概说有个n×m的格子,有两种走法,每种走法都是一个包含D或R的序列,D表示向下走R表示向右走.问从左上角走到右下角的走法有多少种走法包含那两种走法. D要走n次,R要走m次,容易想到用AC自动机 ...
- HDU 2825 AC自动机+DP
题意:一个密码,长度为 n,然后有m个magic words,这个密码至少由k个magic words组成. 问这个密码可能出现的总数. 思路:首先构造AC自动机,由于m很小,才10 ,我们可以使用二 ...
- 多模字符串匹配算法之AC自动机—原理与实现
简介: 本文是博主自身对AC自动机的原理的一些理解和看法,主要以举例的方式讲解,同时又配以相应的图片.代码实现部分也予以明确的注释,希望给大家不一样的感受.AC自动机主要用于多模式字符串的匹配,本质上 ...
- 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 ...
- 【bzoj1030】: [JSOI2007]文本生成器 字符串-AC自动机-DP
[bzoj1030]: [JSOI2007]文本生成器 首先把匹配任意一个的个数的问题转化为总个数-没有一个匹配的个数 先构造AC自动机,然后枚举每一位的字母以及在自动机上的位置 f[i][j]为第i ...
- 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)
已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...
随机推荐
- Banner信息收集和美杜莎使用(9.26 第十二天)
Banner信息收集 Banner信息,欢迎语,在banner信息中可以得到软件开发商.软件名称.版本.服务类型等信息,通过这些信息可以使用某些工具直接去使用相对应的exp去攻击 前提条件:需要和目标 ...
- js 琐碎
1.setTimeout() .setInterval() setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式.(即n毫秒后执行一次) setTimeout(code,n) set ...
- POJ 2481:Cows 树状数组
Cows Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 14906 Accepted: 4941 Description ...
- C语言-存储类&作用域&生命周期&链接属性
1.概念解析(1)存储类 a.存储类就是存储类型,也就是描述C语言变量在何种地方存储. b.内存有多种管理办法:栈.堆.数据段.bss段..text段......一个变量的存储类属性就是描述这个变量存 ...
- CSS - input 美化
input{ padding: 20px; width: 100%; height: 5vh; margin-bottom: 2vh; border-radius: 10vw; border: 0; ...
- SpringAOP切入点的表达式
1. 常用的切入点表达式分为: (1)按类型匹配:within 关键字 (2)按函数匹配:execution (3)按bean的id匹配:bean 2.按类匹配的写法 匹配到具体的类:<aop ...
- JSP页面获取其他页面传递的参数
jstl表达式获取方式: ${param.pid} el表达式获取方式: ${requestScope.attr} el表达式获取方式: ${attr} ---------------------- ...
- redis主要配置项
目录 redisd配置 redis主要配置项 这里就列举两例示例,之后的实验会有详细的示例!! redisd配置 redis主要配置项 bind 0.0.0.0 #监听地址,可以用空格隔开后多个监听I ...
- JMP CALL RET
一.JMP指令(修改EIP的值)(第一个修改EIP的指令) 三种方法 :JMP 立即数 JMP 寄存器 JMP 内存 EIP 之前介绍过,EIP存放的值就是cpu下一次要执行的地址 1.之前学过要 ...
- C#窗体与SQL数据库的连接
/*通过C#winform程序访问数据库数据 用到的命名空间和变量类型: using System.Data.SqlClient; SqlConnection:数据库连接类 SqlCommand:数据 ...