HDU 2222 Keywords Search

模板题。对模式串建立AC自动机然后在trie树上找一遍目标串即可。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
inline int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int trie[N][], top, fail[N]; void init(){top=; mem(trie[],);}
void ins(char *s){
int rt, nxt;
for (rt=; *s; rt=nxt, ++s){
nxt=trie[rt][*s-];
if (!nxt) mem(trie[top],), trie[rt][*s-]=nxt=top++;
}
++trie[rt][];
}
void makefail(){
int u, v, bg, ed;
static int q[N];
fail[]=bg=ed=;
FO(i,,) if ((v=trie[][i])) fail[q[ed++]=v]=;
while (bg<ed){
u=q[bg++];
FO(i,,) {
if ((v=trie[u][i])) fail[q[ed++]=v]=trie[fail[u]][i];
else trie[u][i]=trie[fail[u]][i];
}
}
}
int ac(char *s){
static bool vis[N];
int ans=; mem(vis,);
for (int i=; *s; ++s) {
i=trie[i][*s-];
for (int j=i; j&&!vis[j]; j=fail[j]) vis[j]=, ans+=trie[j][];
}
return ans;
}
char str[];
int main ()
{
int T, n;
scanf("%d",&T);
while (T--) {
scanf("%d",&n); init();
while (n--) scanf("%s",str), ins(str);
scanf("%s",str); makefail();
printf("%d\n",ac(str));
}
return ;
}

HDU 2896 病毒侵袭

把AC自动机的节点维护的东西改一改就行了。不过由于目标串很多,每次都fillchar一遍vis数组会超时。使用以前学的黑科技按时间戳更新vis即可AC。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
inline int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int trie[N][], top, fail[N], ans[], q[N];
bool vis[N];
queue<int>Q; void init(){top=; mem(trie[],);}
void ins(char *s, int id){
int rt, nxt;
for (rt=; *s; rt=nxt, ++s){
nxt=trie[rt][*s-];
if (!nxt) mem(trie[top],), trie[rt][*s-]=nxt=top++;
}
trie[rt][]=id;
}
void makefail(){
int u, v, bg, ed;
fail[]=bg=ed=;
FO(i,,) if ((v=trie[][i])) fail[q[ed++]=v]=;
while (bg<ed){
u=q[bg++];
FO(i,,) {
if ((v=trie[u][i])) fail[q[ed++]=v]=trie[fail[u]][i];
else trie[u][i]=trie[fail[u]][i];
}
}
}
void ac(char *s){
int v;
while (!Q.empty()) v=Q.front(), Q.pop(), vis[v]=;
for (int i=; *s; ++s) {
i=trie[i][*s-];
for (int j=i; j&&!vis[j]; j=fail[j]) {
vis[j]=; Q.push(j);
if (trie[j][]) ans[++ans[]]=trie[j][];
}
}
}
char str[];
int main ()
{
int n, m, total=;
scanf("%d",&n); init();
getchar();
FOR(i,,n) gets(str), ins(str,i);
makefail();
scanf("%d",&m);
getchar();
FOR(i,,m) {
gets(str); ans[]=; ac(str);
if (ans[]) ++total;
else continue;
printf("web %d:",i);
sort(ans+,ans+ans[]+);
FOR(j,,ans[]) printf(" %d",ans[j]);
putchar('\n');
}
printf("total: %d\n",total);
return ;
}

HDU 3065 病毒侵袭持续中

统计每个模式串的出现次数,不用vis数组就行了。这题由于模式串的特殊性,只需要建立26叉树即可。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
inline int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int trie[N][], top, fail[N], num[];
char ss[][]; void init(){top=; mem(trie[],);}
void ins(char *s, int id){
int rt, nxt;
for (rt=; *s; rt=nxt, ++s){
nxt=trie[rt][*s-'A'];
if (!nxt) mem(trie[top],), trie[rt][*s-'A']=nxt=top++;
}
trie[rt][]=id;
}
void makefail(){
int u, v, bg, ed;
static int q[N];
fail[]=bg=ed=;
FO(i,,) if ((v=trie[][i])) fail[q[ed++]=v]=;
while (bg<ed){
u=q[bg++];
FO(i,,) {
if ((v=trie[u][i])) fail[q[ed++]=v]=trie[fail[u]][i];
else trie[u][i]=trie[fail[u]][i];
}
}
}
void ac(char *s){
int v;
for (int i=; *s; ++s) {
if (*s<'A'||*s>'Z') {i=; continue;}
i=trie[i][*s-'A'];
for (int j=i; j; j=fail[j]) if ((v=trie[j][])) ++num[v];
}
}
char str[];
int main ()
{
int n;
while (~scanf("%d",&n)) {
init(); mem(num,);
getchar();
FOR(i,,n) gets(ss[i]), ins(ss[i],i);
makefail();
gets(str);
ac(str);
FOR(i,,n) {
if (!num[i]) continue;
printf("%s: %d\n",ss[i],num[i]);
}
}
return ;
}

AC自动机裸题的更多相关文章

  1. BZOJ-3940:Censoring(AC自动机裸题)

    Farmer John has purchased a subscription to Good Hooveskeeping magazine for his cows, so they have p ...

  2. HDU 2222 AC自动机 裸题

    题意: 问母串中出现多少个模式串 注意ac自动机的节点总数 #include <stdio.h> #include <string.h> #include <queue& ...

  3. HDU 3065 AC自动机 裸题

    中文题题意不再赘述 注意 失配数组 f  初始化一步到位 #include <stdio.h> #include <string.h> #include <queue&g ...

  4. HDU 2896 AC自动机 裸题

    中文题题意不再赘述 注意字符范围是可见字符,从32开始到95 char c - 32 #include <stdio.h> #include <string.h> #inclu ...

  5. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  6. HDU 3065 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...

  7. HDU 2896 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...

  8. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  9. HDU3695(AC自动机模板题)

    题意:给你n个字符串,再给你一个大的字符串A,问你着n个字符串在正的A和反的A里出现多少个? 其实就是AC自动机模板题啊( ╯□╰ ) 正着query一次再反着query一次就好了 /* gyt Li ...

随机推荐

  1. java 关键字super和this

    super关键字 作用:调用父类的构造器 只能出现在子类的构造其中,并且必须是第一行 super()中的参数,决定了调用父类的那个构造器 注:如果子类构造器中没有出现super,则默认加上super( ...

  2. JavaScript基础part2

    JavaScript对象 在JavaScript中除了null和undefined以外其他的数据类型都被定义成了对象,也可以用创建对象的方法定义变量,String.Math.Array.Date.Re ...

  3. 20145234黄斐《Java程序设计》第十周学习总结

    教材学习内容总结 网络概述 概述 网络编程技术是当前一种主流的编程技术,随着联网趋势的逐步增强以及网络应用程序的大量出现,所以在实际的开发中网络编程技术获得了大量的使用. 计算机网络概述 IP地址: ...

  4. hdu 2031 进制转换(栈思想的使用)

    进制转换 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. android学习十三 首选项

    1,首选项可用用来持久保存用户设置,游戏最高分等 2,首选项有,列表首选项,复选框首选项,对话框首选项.. 3,通过xml文件和代码创建首选项      addPreferencesFromResou ...

  6. Odd CSS syntax. [class^='icon-'], [class*=' icon-']

    原文: https://stackoverflow.com/questions/20322740/odd-css-syntax-class-icon-class-icon I am going thr ...

  7. Qt-LCD电子时钟

    先上效果图吧 就是这个样子,简单的时间显示时间. 这里需要注意的是,我们最好建立一个空文件,这里我们需要建立一个集成QLCDNumber的类 具体方法如下图 一下是源代码 digiclock.h #i ...

  8. Linux管道及I/O重定向

    I/O: 系统设定 默认输入设备:标准输入,STDIN,0 默认输出设备:标准输出,STDOUT,1 标准错误输出:STDERR,2 属于不同的数据流 标准输入:键盘 标准输出和错误输出:显示器 I/ ...

  9. 三分钟小课堂-----------------docker(三)增删改查命令

    主要为docker容器的增删改查命令 1  创建容器: docker run   -it   --name 别名  image_name   /bin/bash --name 别名 -d 后台 -t ...

  10. 小程序button 去边框

    /*使用 button::after{ border: none; } 来去除边框*/.free-btn-bordernone{ background: none !important; color: ...