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可以用这种写法解. ...
随机推荐
- rsync错误
rsync error:No route to host rsync服务端开启的iptables防火墙 [root@nfs01 tmp]# rsync -avz /etc/hosts rsync_ba ...
- C# Stream篇(五) -- MemoryStream
MemoryStream 目录: 1 简单介绍一下MemoryStream 2 MemoryStream和FileStream的区别 3 通过部分源码深入了解下MemoryStream 4 分析Mem ...
- 使用FragmentStatePagerAdapter时发现的内存泄露问题
这篇文章想说的并非是由于使用 FragmentStatePagerAdapter 而导致的内存泄漏,内存泄漏的真正原因和 FragmentStaePagerAdapter 并无直接关联,但是使用 Fr ...
- mui下拉刷新 上拉加载
a页面是父页面 b页面是子页面 在b页 html+ js+ 下拉和上拉执行的函数就不贴了 .在这个过程中还遇到了个问题就是刷新的图标偏上 需要改变其高度,需要在a页面里面去改变刷新图标的样式 本文 ...
- hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported
传统样式查询参数(`?`)不再支持:使用JPA样式的序号参数(例如,`?1’) hibernate4.1之后已经对HQL查询参数中的占位符做了改进: 更改代码:
- 微服务和SpringCloud入门
微服务和SpringCloud入门 微服务是什么 微服务的核心是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底去耦合,每个微服务提供单个业务功能的服务,一个服务做一件事情,从技术角度看就是一种 ...
- git使用代理
在使用git科隆一个repo的时候,因为这个repo的子模块是托管在google上的,还是因为gfw导致子模块科隆不下来 只好使用代理了,那么怎么配置git使用代理呢 代码如下 因为我用的是ss所以这 ...
- 2,StructuredStreaming的事件时间和窗口操作
推荐阅读:1,StructuredStreaming简介 使用Structured Streaming基于事件时间的滑动窗口的聚合操作是很简单的,很像分组聚合.在一个分组聚合操作中,聚合值被唯一保存在 ...
- Android进阶——学习AccessibilityService实现微信抢红包插件
在你的手机更多设置或者高级设置中,我们会发现有个无障碍的功能,很多人不知道这个功能具体是干嘛的,其实这个功能是为了增强用户界面以帮助残障人士,或者可能暂时无法与设备充分交互的人们 它的具体实现是通过A ...
- 生成私钥、公钥,配置到Git上
ssh-keygen -t rsa -C "1032671220@qq.com" 输入完毕指令,输入密码.然后会在 /z/.ssh/文件夹下生成一个私钥rsa_id.公钥rsa_p ...