hdu2222这题说的是在一个1000000的长串中找出n个短串是否在其中出现过 最后输出在长串中出现的个数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <string>
using namespace std;
const int maxn =*+;
const int sign_size = ;
map<string,int>ms;
struct Acuth{
int ch[maxn][sign_size];
int val[maxn];
int sz;
int f[maxn];
int last[maxn];
bool use[];
void clear(){
memset(ch[],,sizeof(ch[]));
memset(use,false,sizeof(use));
sz=;
ms.clear();
val[]=;
}
int idx(char c){ return c-'a'; }
void insert(char *s,int v){
int n = strlen(s), u=;
for(int i=; i<n; ++i){
int c=idx(s[i]);
if(ch[u][c]==){
memset(ch[sz],,sizeof(ch[sz]));
val[sz]=;
ch[u][c]=sz++;
}
u=ch[u][c];
}
ms[string(s)]=v;
val[u]=v;
}
void print(int j){
if(j){
use[val[j]] = true;
print(last[j]);
}
}
void find(char *T){
int n = strlen(T);
int j=;
for(int i=; i<n; ++i){
int c = idx(T[i]);
while(j&&!ch[j][c]) j=f[j];
j=ch[j][c];
if(val[j]) print(j);
else if(last[j]) print(last[j]);
}
}
void getFail(){
queue<int> q;
f[]=;
for(int c = ; c<sign_size; ++c){
int u = ch[][c];
if(u){ f[u]=; q.push(u); last[u]=; }
}
while(!q.empty()){
int r= q.front(); q.pop();
for(int c=; c<sign_size; ++c){
int u=ch[r][c];
if(!u){ ch[r][c] = ch[f[r]][c]; continue; }
q.push(u);
int v = f[r];
while(v&&!ch[v][c]) v=f[v];
f[u]=ch[v][c];
last[u] = val[f[u]]?f[u] : last[f[u]];
}
}
}
}ac;
char P[][],text[];
int main()
{
int t;
scanf("%d",&t);
while(t--){
ac.clear();
int n;
scanf("%d",&n);
for(int i=; i<=n; ++i){
scanf("%s",P[i]);
ac.insert(P[i],i);
}
scanf("%s",text);
ac.getFail();
ac.find(text);
int ans=;
for(int i=; i<=n; ++i)
if(ac.use[ms[string(P[i])]]==true) ans++;
printf("%d\n",ans);
}
return ;
}

uva11468 这题给出一些字符和各自对应的选择概率,随机选择L次后将得到一个长度为L 的随机字符串S。给出K个模板串,计算S不包含任何一个串的概率

利用自动机可以快速匹配多个串的特性进行处理,不断地添加在构造的字符串的末尾位置,如果添加构成一个字符串就不添加否则就添加

#include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
const int maxn = *+;
const int sign_size = <<;
struct AUthac{
int ch[maxn][sign_size];
int val[maxn];
int sz;
int f[maxn];
bool match[maxn];
void clear(){
memset(ch[],,sizeof(ch[]));
sz=;
memset(match,false,sizeof(match));
val[]=;
}
void insert(char *s,int v){
int n=strlen(s),u=;
for(int i=; i<n; ++i){
int c = s[i];
if(ch[u][c]==){
memset(ch[sz],,sizeof(ch[sz]));
val[sz]=;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
match[u] = true;
}
void getFail(){
queue<int> q;
f[]=;
for(int c=; c<sign_size; c++){
int u = ch[][c];
if(u){
q.push(u); f[u]=;
}
}
while(!q.empty()){
int r = q.front(); q.pop();
for(int c= ; c<sign_size; ++c){
int u = ch[r][c];
if(u==){
ch[r][c]=ch[f[r]][c];continue;
}
q.push(u);
int v = f[r];
while( v && !ch[v][c] ) v = f[v] ;
f[u]=ch[v][c];
match[u] |= match[f[u]];
}
}
}
}ac;
double pro[sign_size];
char str[sign_size];
int L,n,K;
bool vis[maxn][];
double dp[maxn][];
vector<char> P;
double dfs(int loc,int leave){
if(leave==) return ;
if(vis[loc][leave]==true) return dp[loc][leave];
double ans=;
for(int i=; i<n; ++i){
int c = P[i];
if(ac.match[ac.ch[loc][c]]==false)
ans+= pro[i] * dfs( ac.ch[loc][c], leave - );
}
vis[loc][leave] = true;
dp[loc][leave] = ans;
return ans;
}
int main()
{
int t,cas=;
char S[];
scanf("%d",&t);
while(t--){
ac.clear();
scanf("%d",&K);
for(int i=; i<=K; ++i){
scanf("%s",S);
ac.insert(S,i);
}
ac.getFail();
scanf("%d",&n);
P.clear();
for(int i =; i<n; i++){
scanf("%s",str);
P.push_back(str[]);
scanf("%lf",&pro[i]);
}
memset(vis,false,sizeof(vis));
scanf("%d",&L);
double ans=dfs(,L);
printf("Case #%d: %.6lf\n",++cas,ans);
}
return ;
}

uva11019

题意 给出一个n*m的字符矩阵T,你的任务是找出给定的x*y的字符矩阵P出现了多少次。 即需要在二维文本串T中查找二维模式串P。

因为是以矩阵P为模板然后将P的每行都挂在自动机上接下来,如果存在相同的串就讲该串与上一个相同的串用一个next数组存下关系,接下来将文本矩阵T每行都去与自动机匹配每当匹配到一行是 这个行所在的那个矩阵可匹配个数加1(cnt[r][c]表示以r行c列为左上角的矩阵)

做完所有的行后 统计每个位置为起始点的可匹配数如果等于x那么这就是一个可匹配的矩阵。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
using namespace std;
const int maxn = *+;
const int sign_size = ;
int cnt[][],len[];
struct Acuthmechion{
int ch[maxn][sign_size];
int val[maxn];
int sz;
int next[maxn];
int f[maxn],last[maxn];
int idx(char c){ return c-'a'; }
void clear(){
sz=;
val[]=;
memset(ch[],,sizeof(ch[]));
memset(cnt,,sizeof(cnt));
}
void insert(char *s,int v){
int n=strlen(s),u=;
len[v]=n;
for(int i=; i<n; ++i ){
int c = idx(s[i]);
if(ch[u][c]==){
memset(ch[sz],,sizeof(ch[sz]));
val[sz]=;
ch[u][c]=sz++;
}
u=ch[u][c];
}
next[v]=val[u];
val[u]=v;
}
void print(int row,int colun, int j){
if(val[j]){
for(int i = val[j]; i!=; i=next[i]){
int t1 = row-(i-);
int t2 = colun-(len[i]-);
if(t1>=&&t2>=) ++cnt[t1][t2];
}
print(row,colun,last[j]);
}
}
void find(char *T,int row){
int n=strlen(T);
int j=;
for(int i=; i<n; ++i){
int c = idx(T[i]);
while(j&&ch[j][c]==) j=f[j];
j=ch[j][c];
if(val[j]) print(row,i,j);
else if(last[j]) print(row,i,last[j]);
}
}
void geiFail(){
queue<int> q;
last[]=f[]=;
for(int c=; c<sign_size; ++c){
int u=ch[][c];
if(u){ f[u]=; q.push(u); last[u]=;}
}
while(!q.empty()){
int r = q.front(); q.pop();
for(int c=; c<sign_size; ++c){
int u = ch[r][c];
if(u==){
ch[r][c]=ch[f[r]][c]; continue;
}
q.push(u);
int v=f[r];
while(v&&ch[v][c]==) v=f[v];
f[u]=ch[v][c];
last[u]=val[f[u]] ? f[u]:last[f[u]];
}
}
}
}ac;
char xy[][];
char nm[][];
int main()
{
int cas,n,m,x,y;
scanf("%d",&cas);
while(cas--){
ac.clear();
scanf("%d%d",&n,&m);
for(int i=; i<n; ++i)
scanf("%s",nm[i]);
scanf("%d%d",&x,&y);
for(int i=; i<x; ++i){
scanf("%s",xy[i]);
ac.insert(xy[i],i+);
}
ac.geiFail();
for(int i=; i<n; ++i){
ac.find(nm[i],i);
}
int ans=;
for(int i=; i<n; ++i)
for(int j=; j<n; ++j)
if(cnt[i][j]==x) ans++;
printf("%d\n",ans);
}
return ;
}

ac自动机系列的更多相关文章

  1. HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)

    小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  2. HDU4511 小明系列故事——女友的考验 —— AC自动机 + DP

    题目链接:https://vjudge.net/problem/HDU-4511 小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others)    Memor ...

  3. HDU4511 小明系列故事——女友的考验(AC自动机 + DP)

    题目大概说有平面有n个点,从1点出发走到n点,每一步只能走到序号比当前更大的点且走的序列不能包含给定的m个序列中的任何一个,问1走到n的最短路. 用m个序列建个AC自动机,后缀包含整个序列的结点标记一 ...

  4. HDU-4534 郑厂长系列故事——新闻净化 AC自动机+DP

    题意:给定一些单词,这些单词必须要是一个目标串的子串,同时给定一些串,这些串不能够出现在目标串中,其余一些串只会带来不同附加值.现在问满足前两者的情况下,要求附加值最大.数据给定一个原始串,现在要求在 ...

  5. HDU-4518 吉哥系列故事——最终数 AC自动机+数位DP

    题意:如果一个数中的某一段是长度大于2的菲波那契数,那么这个数就被定义为F数,前几个F数是13,21,34,55......将这些数字进行编号,a1 = 13, a2 = 21.现给定一个数n,输出和 ...

  6. 中文分词系列(二) 基于双数组Tire树的AC自动机

    秉着能偷懒就偷懒的精神,关于AC自动机本来不想看的,但是HanLp的源码中用户自定义词典的识别是用的AC自动机实现的.唉-没办法,还是看看吧 AC自动机理论 Aho Corasick自动机,简称AC自 ...

  7. 【无聊放个模板系列】BZOJ 3172 (AC自动机)

    #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #inc ...

  8. 小明系列故事――女友的考验 HDU - 4511 AC自动机+简单DP

    题意:自己看题目,中文体面. 题解: 把所有不能走的路径放入AC自动机中. 然后DP[i][j]表示走到 i 这个点,且位于AC自动机 j 这个节点最短距离 然后直接DP即可.注意一点会爆int #i ...

  9. HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)题解

    题意:从 1 走到 n,要求所走路径不能出现给定的路径,求最短路 思路:因为要求不能出现给定路径,那么我可以求助ac自动机完成判断. 我们可以在build的时候标记哪些路径不能出现,显然下面这种表示后 ...

随机推荐

  1. python2.0_s12_day19_前端结合后端展示客户咨询纪录

    接下来就是将后台视图与前端页面结合起来了完成后台系统了.实现前端展示用户列表1.先在base.html代码中把模版中Dashboard下面的内容清空,如下: 具体删除哪些html代码,自己找吧.2.我 ...

  2. Hbase的基本认识

    1.使用场景:实时查询交互 说说概念性的东西,方便今后更加深入的理解. HBase是Apache Hadoop中的一个子项目,Hbase依托于Hadoop的HDFS作为最基本存储基础单元,通过使用ha ...

  3. kafka中配置细节

    今天遇到kafka发送消息的时候,一直报Kafka“Failed to send messages after 3 tries”错误,根据网上找问题,修改各种配置参数,各种重启,还是解决不了问题. 郁 ...

  4. PHP webservice 接口实例

    原文地址,就不摘抄了 http://www.sky00.com/archives/91.html

  5. 日记整理---->2016-11-01

    这里我们整理一下项目的流程,一般来说做一个模块之前.会有需求文档.页面原型和接口文档. 一. js获取radio的值 页面的html代码: <ul class="list-group& ...

  6. java三方---->dom4j解析xml数据

    Dom4j是一个易用的.开源的库,用于XML,XPath和XSLT.它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP.今天我们就开始Dom4j的学习. Dom4j的使用 ...

  7. Android中textView自动识别电话号码,电子邮件,网址(自动加连接)

    extends:http://blog.csdn.net/wx_962464/article/details/8471195 其实这个是很简单的,在android中已经为我们实现了,但是我估计很多人都 ...

  8. mysql数据库新插入数据,需要立即获取最新插入的id

    在MySQL中,使用auto_increment类型的id字段作为表的主键.通常的做法,是通过“select max(id) from tablename”的做法,但是显然这种做法需要考虑并发的情况, ...

  9. 探究 Oracle 高水位对数据库性能影响

    在开始深入分析之前,让我们先来了解一下高水位线 HWM. 一. HWM 的基本原理 (概念) 在 Oracle 中,高水位线(High-warter mark, HWM)被用来形容数据块的使用位置,即 ...

  10. 【css a标签 鼠标悬浮时变手型】

    <a href="#" style="cursor:pointer">