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_day18_django_admin

    Django admin的个性化定制首先我们看下,前面章节中定义的models在admin后台管理界面的样子: 然后我们看下老男孩教育点名平台的admin管理表的后台界面样子: admin管理后台常用 ...

  2. window 后台执行 redis(隐藏窗口)

    方法是在知乎上看的,链接:https://www.zhihu.com/question/22771030 实现方法是利用一个vbe脚本去运行一个bat脚本,在bat脚本里启动exe软件 PS:要想启动 ...

  3. docker学习-docker容器

  4. N76E003学习之路(二)

    最近一直在想N76E003和STM8M003的对比情况,在网上找了不少资料,看了不少文档,具体总结如下: STM8S003F3P6:一共20个脚,最多支持16个GPIO,支持16个外部中断:2个16位 ...

  5. mySQL数据库一:数据类型

    integer(整型)varchar(字符串类型,必须要跟最大字符串)text(大文本)float(单精度,即七到八位有效数字)double(双精度,即15到16位有效数字)date(只有年月日)ti ...

  6. 《C++ Primer Plus》第15章 友元、异常和其他 学习笔记

    友元使得能够为类开发更灵活的接口.类可以将其他函数.其他类和其他类的成员函数作为友元.在某些情况下,可能需要前向声明,需要特别注意类和方法声明的顺序,以正确地组合友元.潜逃类是在其他类中生命的类,它有 ...

  7. option 选不中问题

    function appAndBuz(appName,buzName,areaCenterCode){ //appName,buzName下拉框的值start $.ajax({ type: " ...

  8. solr删除数据的4种方便快捷的方式

    1.在solr客户端,访问你的索引库(我认为最方便的方法) 1)documents type 选择 XML  2)documents 输入下面语句 <delete><query> ...

  9. 【mysql】mysql front 提示Access violation at address 010C9CD0 in module ‘mysql-front.exe’

    1 错误描述: 利用mysql-front 工具新建数据库.提示了一下错误 2 解决办法: 内存越界问题,最好重新注册下Windows的动态链接库 首先“开始”—“cmd” 在打开的dos窗口中运行

  10. LeetCode——Search for a Range

    Description: Given a sorted array of integers, find the starting and ending position of a given targ ...