题目链接

题意 : 中文题、点链接

分析 :

直接建 Trie 图、在每一个串的末尾节点记录其整串长度、方便删串操作

然后对于问询串、由于可能有删串操作

所以在跑 Trie 图的过程当中需要拿个栈记录一下路径

跑 Trie 图的意思就是说将问询串字符一个个拿出来

然后一直找当前节点的下一个对应字母的节点

由于是 Trie 图、所以在 Fail 的时候也会自动跑到对应的节点

这和普通的 AC 自动机不一样、在 Fail 的时候要每次暴力跳 Fail 节点

然后直接模拟即可

#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long

#define scl(i) scanf("%lld", &i)
#define scll(i, j) scanf("%lld %lld", &i, &j)
#define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k)
#define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l)

#define scs(i) scanf("%s", i)
#define sci(i) scanf("%d", &i)
#define scd(i) scanf("%lf", &i)
#define scIl(i) scanf("%I64d", &i)
#define scii(i, j) scanf("%d %d", &i, &j)
#define scdd(i, j) scanf("%lf %lf", &i, &j)
#define scIll(i, j) scanf("%I64d %I64d", &i, &j)
#define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k)
#define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k)
#define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k)
#define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l)
#define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l)
#define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l)

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define lowbit(i) (i & (-i))
#define mem(i, j) memset(i, j, sizeof(i))

#define fir first
#define sec second
#define VI vector<int>
#define ins(i) insert(i)
#define pb(i) push_back(i)
#define pii pair<int, int>
#define VL vector<long long>
#define mk(i, j) make_pair(i, j)
#define all(i) i.begin(), i.end()
#define pll pair<long long, long long>

#define _TIME 0
#define _INPUT 0
#define _OUTPUT 0
clock_t START, END;
void __stTIME();
void __enTIME();
void __IOPUT();
using namespace std;
;
;
;

char ans[max_len];
int pos[max_len];
;

struct Aho{
    struct StateTable{
        int nxt[Letter];
        int fail, cnt, len;
        bool vis;
        void init(){
            memset(nxt, , sizeof(nxt));
            fail = ;
            cnt = ;
            len = ;
            vis = false;
        }
    }Node[max_node];

    int sz;
    queue<int> que;

    inline ].init(); sz = ; }

    inline void insert(char *s, int len){
        ;
        ; i<len; i++){
            int idx = s[i] - 'a';
            if(!Node[now].nxt[idx]){
                Node[sz].init();
                Node[now].nxt[idx] = sz++;
            }
            now = Node[now].nxt[idx];
        }
        Node[now].len = len;
        Node[now].cnt++;
    }

    inline void build(){
        Node[].fail = -;
        que.push();
        while(!que.empty()){
            int top = que.front();  que.pop();
            ; i<Letter; i++){
                if(Node[top].nxt[i]){
                    ) Node[ Node[top].nxt[i] ].fail = ;
                    else{
                        int v = Node[top].fail;
                        ){
                            if(Node[v].nxt[i]){
                                Node[ Node[top].nxt[i] ].fail = Node[v].nxt[i];
                                break;
                            }v = Node[v].fail;
                        }) Node[ Node[top].nxt[i] ].fail = ;
                    }que.push(Node[top].nxt[i]);
                }?Node[ Node[top].fail ].nxt[i]:;
            }
        }
    }

//    int Match(char *s){
//        int now = 0, res = 0;
//        for(int i=0; s[i]!='\0'; i++){
//            int idx = s[i] - 'a';
//            now = Node[now].nxt[idx];
//            int tmp = now;
//            while(tmp != 0 && !Node[tmp].vis){
//                res += Node[tmp].cnt;
//                Node[tmp].vis = true;
//                Node[tmp].cnt = 0;
//                tmp = Node[tmp].fail;
//            }
//        }
//        return res;
//    }

    void query(char * s){
        int len = strlen(s);
        ;
        pos[now] = now;
        ; i<len; i++){
            int idx = s[i] - 'a';
            now = Node[now].nxt[idx];
            pos[++top] = now;
            ans[  top] = s[i];
            ){
                top -= Node[now].len;
                now = pos[top];
            }
        }
        ; i<=top; i++) putchar(ans[i]); puts("");
    }

}ac;

char str[max_len];
char tmp[max_len];

int main(void){__stTIME();__IOPUT();

    scs(str);

    int len = strlen(str);

    int n;

    sci(n);

    ac.init();

    ; i<n; i++){
        scs(tmp);
        ac.insert(tmp, strlen(tmp));
    }

    ac.build();

    ac.query(str);

__enTIME();;}

void __stTIME()
{
    #if _TIME
        START = clock();
    #endif
}

void __enTIME()
{
    #if _TIME
        END = clock();
        cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl;
    #endif
}

void __IOPUT()
{
    #if _INPUT
        freopen("in.txt", "r", stdin);
    #endif
    #if _OUTPUT
        freopen("out.txt", "w", stdout);
    #endif
}

BZOJ 3940 Censoring ( Trie 图 )的更多相关文章

  1. 【Trie图】BZOJ3940-[Usaco2015 Feb]Censoring

    [题目大意] 有一个匹配串和多个模式串,现在不断删去匹配串中的模式串,求出最后匹配串剩下的部分. [思路] 众所周知,KMP的题往往对应着一道AC自动机quq.本题同BZOJ3942(KMP),这里改 ...

  2. BZOJ 1030 [JSOI2007]文本生成器 (Trie图+DP)

    题目大意:给你一堆字符串,一个串不合法的条件是这些字符串中任意一个是这个串的子串,求合法的串的数量 其实这道题比 [HNOI2008]GT考试 那道题好写一些,但道理是一样的 只不过这道题的答案可以转 ...

  3. BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)

    题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...

  4. BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)

    BZOJ1195 LOJ10061 题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$ 首先对所有模式串构造$Trie$图,$Trie ...

  5. AC自动机相关Fail树和Trie图相关基础知识

    装载自55242字符串AC自动机专栏 fail树 定义 把所有fail指针逆向,这样就得到了一棵树 (因为每个节点的出度都为1,所以逆向后每个节点入度为1,所以得到的是一棵树) 还账- 有了这个东西, ...

  6. 【BZOJ-2938】病毒 Trie图 + 拓扑排序

    2938: [Poi2000]病毒 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 609  Solved: 318[Submit][Status][Di ...

  7. 【hihoCoder】1036 Trie图

    题目:http://hihocoder.com/problemset/problem/1036 给一个词典dict,词典中包含了一些单词words.要求判断给定的一个文本串text中是否包含这个字典中 ...

  8. 【hihoCoder 1036】Trie图

    看了一下简单的$Trie图$,调模板调啊调一连调了$2h$,最后发现$-'a'$打成$-'A'$了hhh,有种摔键盘的冲动. $Trie图$是$Trie树$上建立“前缀边”,不用再像在$Trie树$上 ...

  9. 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组

    涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...

随机推荐

  1. oracle查询表的结构

    SELECT t.table_name,t.column_name,t.data_type||'('||t.data_length||')', t1.comments FROM User_Tab_Co ...

  2. Minicom 简单使用

    一. 什么是minicom 1.1. minicom 是linux 下的一个串口调试工具 二. minicom的使用 2.1. 进入设置 sudo minicom -s 2.1.1. 串口设置 i. ...

  3. Jave Web使用的设计模型

    Jave Web使用的设计模型 Mybatis 源码解读-设计模式总结 ImportNew 5月15日 (给ImportNew加星标,提高Java技能) 作者:crazyant www.crazyan ...

  4. 剑指offer-构建乘积数组-数组-python

    题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不 ...

  5. ELK视频下载

    Elasticsearch , Logstash, Kibana 相关视频下载地址:Beats.Elastic Stack.ElasticSearch.Kibana.Logstash下载地址:链接:h ...

  6. luogu P3226 [HNOI2012]集合选数

    luogu 因为限制关系只和2和3有关,如果把数中2的因子和3的因子都除掉,那剩下的数不同的数是不会相互影响,所以每次考虑剩下的数一样的一类数,答案为每类数答案的乘积 如果选了一个数,那么2的因子多1 ...

  7. html基础知识(总结自www.runoob.com)

    HTML属性 属性 描述 class 为html元素定义一个或多个类名(classname)(类名从样式文件引入) id 定义元素的唯一id style 规定元素的行内样式(inline style) ...

  8. 移动端 app

    上传到蒲公英

  9. Nginx默认配置语法

    Nginx默认配置语法 1. 我们进入  /etc/nginx/目录下,打开  nginx.conf文件 2. 我们来解析下 这里面标签和各模块的作用 # 设置nginx服务的系统使用用户 user ...

  10. oracle 使用问题

    12541: 典型的listener.ora 文件内容: SID_LIST_LISTENER =   (注册到监听器的service name所在区域)  (SID_LIST =    (SID_DE ...