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. js遍历商品编码

    function bathAuditGoods(state) { var selections = $("#deliveryGrid").datagrid('getSelectio ...

  2. 我们复习.Net的这些日子里

    今天是我们复习前面学习的第三天,也是在今天我们结束了复习.之前上学时间感觉知识全是生僻的,在生活中很少用到,因此喜欢重复的记忆,而现在学习的知识全是现在乃至未来,将是每天我们使用的,所以就感觉没必要重 ...

  3. JS-cookie封装

    智能社学习笔记 <script type="text/javascript"> /*****设置cookie*****/ function setCookie(name ...

  4. Java可视化JVM监控软件

    jdk自带.jdk安装目录下 1.JConsole 选择 不安全 可用不多 2.VisualVM

  5. 高中生的IT之路-1.5西餐厅服务生

    之所以说漫长的求职,是因为培训结束后半年左右没有找到工作. 每次面试结束后,得到的都是“回去等消息”,然后就杳无音信了.一次次的面试,一次次的失败,一次次查找失败的原因.总结来看主要有两点:一是没有工 ...

  6. 树链剖分-点的分治(dis[i]+dis[j]==k的点对数量)

    poj2114 Boatherds Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1195   Accepted: 387 ...

  7. mysql常见的错误码

    Mysql错误代码 Mysql错误代码分为两部分,老版本一部分,4.1版本为新的部分 第一部分: mysql的出错代码表,根据mysql的头文件mysql/include/mysqld_error.h ...

  8. mysql中or和in的效率问题

    分三中情况进行测试,分别是:第一种情况:in和or所在列为主键的情形.第二种情况:in和or所在列创建有索引的情形.第二种情况:in和or所在列没有索引的情形.每种情况又采用不同的in和or的数量进行 ...

  9. EF的使用(DbContext对象的共用问题)

    1.问题的引入 对于某一个数据库的EF操作对象,当执行某一次请求的时候,可能会多次操作数据库,也就是可能创建很多MyDbContext(继承自DbContext对象,EF上下文对象) 2.代码创建 当 ...

  10. PGA结构

    当客户端向服务器发送连接请求,服务器监听到客户端的请求,在专用服务器模式下,会在服务器端衍生一个server process来代理客户的请求,server process进而向实例发起连接,创建会话, ...