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. ionic 页面加载事件及loading动画

    页面加载完成事件(非刷新情况下,页面切换是不会重复触发此事件的,只在第一次进入页面时触发,需要重复触发的话请使用 $ionicView.enter 事件) angular.module('app.co ...

  2. 【渗透测试学习平台】 web for pentester -5.代码执行

    Example 1 http://192.168.106.154/codeexec/example1.php?name=".system('uname -a');// Example 2 h ...

  3. oracle数据库字符集

    Oracle字符集的基本原理 1. Oracle服务器字符集 oracle以哪种字符编码存储字符,可以通过以下语句查出数据库字符集的设置. 方法1 SQL> select * from v$nl ...

  4. NUC131的系统管理

    系统复位系统复位可以由如下的任何一种中断实现,这些复位中断标志可以通过寄存器RSTSRC读取. 上电复位 nRESET引脚低电平复位 看门狗复位 低压复位 欠压检测器复位 CPU 复位 ...

  5. 预装的Office2016,文件图标表显示以及新建失败问题解决 方法

    新购买笔记本电脑,预装的office2016 学生版 启动激活后,会出现文件图标异常, 文件的类型为: ms-resource:Strings/FtaDisplayName.docx (.docx) ...

  6. LeetCode——pow(x, n)

    超时了,只能先这么干了. return Math.pow(x, n);

  7. nutch 1.7导入Eclipse

    1.下载Nutch1.7的包 apache-nutch-1.7-src.zip,解压之后应该包括 bin,conf,src等目录 2.将解压之后的 apache-nutch-1.7 文件夹放到ecli ...

  8. ios Quartz 各种绘制图形用法

    摘要: CoreGraphics的功能非常强大,可以绘制各种图形:今天学习一下怎么绘制简单的点线面,记录学习. 一.导入coreGraphics.framework 二.绘制图形 1.绘制矩形 // ...

  9. 音频的录制和播放功能(audio) ---- HTML5+

    模块:audio Audio模块用于提供音频的录制和播放功能,可调用系统的麦克风设备进行录音操作,也可调用系统的扬声器设备播放音频文件.通过plus.audio获取音频管理对象. 应用场景:音频录制, ...

  10. 170620、springboot编程之页面版Hello World

    书接上回,把Hello World 在页面上显示! 1.在pom文件中加入web支持 <dependency> <groupId>org.springframework.boo ...