Luogu_P2536 [AHOI2005]病毒检测 trie树+dfs

Luogu_P2536 [AHOI2005]病毒检测

### trie树+dfs

题目链接
这两个符号比较有意思
可以把所有的串都先建到trie树上
然后用病毒的模式串在上面搜索
处理这两个符号就可以通过搜索次序解决
主要可以看代码
问的是非病毒,WA了
一个符号可以不取,又WA了



代码如下:

#include<bits/stdc++.h>
using namespace std;
string bd,w[1010];
int ans,n,trie[250010][10],tot=1,ed[250010],ls;
inline int id(char a){
    if(a=='A') return 1;
    if(a=='G') return 2;
    if(a=='C') return 3;
    if(a=='T') return 4;
}
inline void insert(string s){
    int p=1,len=s.length();
    for(int k=0;k<len;k++){
        int ch=id(s[k]);
        if(!trie[p][ch]) trie[p][ch]=++tot;
        p=trie[p][ch];
    }
    ed[p]++;
}
bitset<1100> f[250010];
void dfs(int p,int t){
    if(t==ls){
        ans+=ed[p];ed[p]=0;return;
    }
    if(f[p][t]) return;f[p][t]=1;
    if(bd[t]>='A' && bd[t]<='Z'){
        int ch=id(bd[t]);
        if(!trie[p][ch]) return;
        p=trie[p][ch];
        dfs(p,t+1);
    }else{
        if(bd[t]=='?'){
            for(int i=1;i<=4;i++) if(trie[p][i]) dfs(trie[p][i],t+1);
        }else{
            dfs(p,t+1);
            for(int i=1;i<=4;i++) if(trie[p][i]){
                dfs(trie[p][i],t+1);dfs(trie[p][i],t);
            }
        }
    }
}
int main()
{
    cin>>bd>>n;
    ls=bd.length();
    for(int i=1;i<=n;i++) cin>>w[i],insert(w[i]);
    dfs(1,0);
    printf("%d\n",n-ans);
    return 0;
}

原文地址:https://www.cnblogs.com/ChrisKKK/p/11728289.html

时间: 2024-11-04 22:14:39

Luogu_P2536 [AHOI2005]病毒检测 trie树+dfs的相关文章

[AHOI2005] 病毒检测 - Trie,BFS

给定一个模板串,里面带有 * (可以匹配任意一段可以为空的串)和 ? (可以匹配任意一个字母),然后给定 \(n\) 个询问串,问有多少询问串不能匹配.\(n \leq 500, len \leq 1000\) Solution 对所有询问串建立字典树,然后考虑一个 BFS 过程,状态表示为 \((i,j)\),即模板串正要处理第 \(i\) 个字符,而字典树上走到了 \(j\) 位置,然后讨论模板串的这一位来转移 如果模板串的这一位是字母,则模板串走一位,结点走对应字母的转移边 如果模板串的这

Trie树 + DFS - CSU 1457 Boggle

Boggle Problem's Link: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1457 Mean: 给定n个串,有m个询问. 每个询问给你一个4*4的字符矩阵,你可以在这个字符矩阵中任意字符出发,向四个方向走(已走过的不可重复走),走出一个字符串. 如果n个串中有对应的串和走出的字符串相同,那么需要求出: 1.不同长度的串给了不同的权值,n个串中出现的串的总权值是多少? 2.从出现的字符串中找一个最长的出来,如果有多个,找一个字典

【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病毒.实验在一个封闭的局域网内进行.局域网内有n台计算机,编号为1~n.一些计算机之间通过网线直接相连,形

poj 2418 Hardwood Species (trie树)

poj   2418   Hardwood Species http://poj.org/problem?id=2418 trie树+dfs 题意: 给你多个单词,问每个单词出现的频率. 方法:通过字典树,将所有单词放入树中,通过dfs遍历(题目要求按ASSIC码顺序输出单词及其频率),dfs可满足 注意:单词中不一定只出现26个英文字母,ASSIC码表共有256个字符 1 #include <stdio.h> 2 #include <string.h> 3 #include &l

BZOJ 3439 Kpm的MC密码 Trie树+可持久化线段树

题目大意:给定n个字符串,对于每个字符串求以这个字符串为后缀的字符串中第k小的编号 首先将字符串反转 那么就变成了对于每个字符串求以这个字符串为前缀的字符串中第k小的编号 然后考虑对字符串排序 那么对于每个字符串以它为前缀的字符串一定是连续的 那么就转化成了区间第k小 这个用可持久化线段树可以解决 排序自然不能直接排 既然是字符串 考虑Trie树+DFS即可 注意字符串有重复的 小心 #include <vector> #include <cstdio> #include <

BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对dfs序建可持久化的trie树.这样做的空间复杂度是O(nw),时间复杂度是O(nw). 代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=102000; 5 6 int n,q; 7 int v[maxn

[POJ] #1003# 487-3279 : 桶排序/字典树(Trie树)/快速排序

一. 题目 487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 274040   Accepted: 48891 Description Businesses like to have memorable telephone numbers. One way to make a telephone number memorable is to have it spell a memorable word or

[ACM] POJ 2418 Hardwood Species (Trie树或map)

Hardwood Species Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 17986   Accepted: 7138 Description Hardwoods are the botanical group of trees that have broad leaves, produce a fruit or nut, and generally go dormant in the winter. Ameri

[ACM] POJ 2418 Hardwood Species (Trie树或者map)

Hardwood Species Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 17986   Accepted: 7138 Description Hardwoods are the botanical group of trees that have broad leaves, produce a fruit or nut, and generally go dormant in the winter. Ameri