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可以用这种写法解. ...
随机推荐
- 047-PHP数字前面补零,固定位数补0
<?php #PHP 数字前面补零 固定位数补0 $num=128; $num=str_pad($num,8,"0",STR_PAD_LEFT); echo $num; // ...
- 158-PHP strstr函数输出第一次出现字符串的位置到字符串结尾的所有字符串
<?php $str='PHP is a very good programming language!'; //定义一个字符串 echo '第一次出现字母l的位置到字符串结尾的所有字符串'.s ...
- 干货分享:如何搞定Essay Paragraph部分?
想要写出一篇高质量的留学生作业,首先要从写好段落(paragraph)开始.那么今天就随小编一起来看看,如何写好Paragraph部分? 段落:在英文中我们俗称为paragraph,而一篇英文文章通常 ...
- 实验吧-杂项-你没有见过的加密!(php srand()和rand()函数)
什么垃圾东西,弄半天,Windows上运行乱码,linux上7.3的php运行也是乱码(气死). 下载文件,查看内容 <?php function encrypt($str) { $crypte ...
- webpack散记--Typescript
Typescript 1.js的超集 官网:typescriptlang.org/tslang.cn 来自:微软 安装:官方的 npm i typescript ts-loader --save-d ...
- java的JDBC的事务学习
https://www.cnblogs.com/chy18883701161/p/11372089.html
- vagrant 学习笔记
之所以学习他是因为最近换了电脑 又要重新搭环境 很烦躁然后就有了然后 1.先安装 virtualbox2.安装 vagrant3.安装xshell4.重启5.下载系统镜像 (可以去vagrant官网 ...
- Swift 3必看:从使用场景了解GCD新API
https://www.jianshu.com/p/fc78dab5736f 2016.10.06 21:59* 在学习Swift 3的过程中整理了一些笔记,如果想看其他相关文章可前往<Swif ...
- 代码神器:拒绝重复编码,这款IDEA插件了解一下.....
作者:HeloWxl www.jianshu.com/p/e4192d7c6844 Easycode是idea的一个插件,可以直接对数据的表生成entity.controller.service.da ...
- PAT 2014 秋
A 1084 Broken Keyboard 注意大小写即可. #include <cstdio> #include <iostream> #include <algor ...