Nowcoder contest 392 J (模板题)【序列自动机】

<题目链接>

题目大意:
给你一个母串A,然后进行q次询问,每次询问给定一个长度不超过母串的字符串,问你这个字符串是否是母串的子串。

解题分析:
序列自动机模板题。本题的思想就是考虑贪心的去匹配,我们希望当前匹配到的位置越靠前越好。所以对于母串每一位都记一下下一次出现某个字符的位置。匹配的时候从第零位(虚根)开始,如果能一直匹配下去就是$Yes$ ,否则就是 $No$,这些操作就是用序列自动机简单实现。

单次查询的复杂度是$O(|B_i|)$ 的,序列自动机预处理的复杂度是 $O(26|A|)$的。总时间复杂度是$O(26|A|+\sum_{i=1}^N |B_i|)$。

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6+5;
int n,m,T;
char str[N],s[N];
int nxt[N][26],pos[26];

void init(){     //预处理主串的信息
    n=strlen(str+1);
    for(int i=0;i<26;i++) pos[i]=n+1;    //a~z中每个字母的下一个字母所对应的位置
    for(int i=n;~i;i--){
        for(int j=0;j<26;j++)
            nxt[i][j]=pos[j]; //记录下下一次出现这个字符的位置
        pos[str[i]-‘a‘]=i;    //更新a[i]最对应的字母对应的当前最靠前的位置
    }
}
bool solve(){
    scanf("%s",s+1);
    m=strlen(s+1);int x=0;   //x从0开始,0作为虚根
    for(int i=1;i<=m;i++){
        int v=s[i]-‘a‘;
        if(nxt[x][v]==n+1) return false;    //如果下一个出现字符的位置不存在,则说明该子串并未完全匹配
        x=nxt[x][v];
    } return true;
}

int main(){
    scanf("%s",str+1);
    cin>>T;init();
    while(T--) solve()?puts("Yes"):puts("No");
}

原文地址:https://www.cnblogs.com/00isok/p/10503988.html

时间: 2024-10-08 05:12:29

Nowcoder contest 392 J (模板题)【序列自动机】的相关文章

迪杰斯特拉算法 最短路径模板题 hdu 2544

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 36954    Accepted Submission(s): 16091 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找

HDU-2222 Keywords Search(AC自动机--模板题)

题目大意:统计一共出现了多少次模板串. 题目分析:AC自动机的模板题.不过这题有坑,相同的模板串不能只算一次. 代码如下: # include<iostream> # include<cstdio> # include<queue> # include<map> # include<string> # include<cstring> # include<algorithm> using namespace std; co

NYOJ 1085 数单词 (AC自动机模板题)

数单词 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 为了能够顺利通过英语四六级考试,现在大家每天早上都会早起读英语. LYH本来以为自己在6月份的考试中可以通过六级,可是没想到,成绩出来以后,居然没有通过.所以他不得不付出更多的时间来学习英语. 要想通过六级,最基本的要求就是词汇量.为了能够更快的记住一些陌生单词,LYH有时会找一些英语文章来读. 今天早上,LYH又找了一篇文章.读之前,他突然萌生出一个想法:文章中哪些单词出现的次数最多呢? 输入 第一行输入一个

【HDU】病毒侵袭(AC自动机模板题)

AC自动机的模板题,由于输入的字符串中的字符不保证全为小写字母,所以范围应该在130之前,而前31位字符是不可能出现在字符串的(不懂得查下ACSII表就行了),所以只需要开的结点数组大小为130足够了,如果开256就会内存超限. 11908775 2014-10-19 10:45:38 Accepted 2896 250MS 29596K 2760 B G++ KinderRiven 输入只有一组,所以不用担心超时的问题. #include<queue> #include<cstdio&

HDU 2896 (AC自动机模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串. 解题思路: AC自动机模板题.注意一下字符范围. cnt记录这个模式串的个数改为这个模式串的index. find的时候,把找到的index压入vector里面即可. 注意有多个匹配串,每次find之后会把last->cnt修改,原因是防止一个模式串出现了多次被压入vector,所以先备份一下,

AC自动机(附洛谷P3769模板题)

首先,介绍一下AC自动机(Aho-Corasick automaton),是一种在一个文本串中寻找每一个已给出的模式串的高效算法. 在学习AC自动机之前,你需要先学习Trie树和KMP算法,因为AC自动机正式利用并结合了两者的思想. 说到实际的不同,其实AC自动机只是在Trie树上引入了一个类似KMP中next数组的东西叫做Fail指针. 对于每一个节点,Fail指针指向该节点所代表的字符串中,次长的.在Trie树中存在的后缀(因为最长的在Trie树种存在的后缀就是其本身)所代表的节点. 举例:

静态RMQ模板题 contest 静态RMQ T2

Description Wind设计了很多机器人.但是它们都认为自己是最强的,于是,一场比赛开始了.机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛.首先,他们面前会有一排共n个数,它们比赛看谁能最先把每连续k个数中最大和最小值写下来,当然,这些机器人运算速度都很快,它们比赛的是谁写得快.但是Wind也想知道答案,你能帮助他吗? Input 每组测试数据,第1行为n,k,第2行共n个数,为数字序列,所有数字均在longint范围内. Output 共n-k+1行 第i行为第i-i+k-1

LA 4670 出现次数最多的子串 (AC自动机模板题)

Dominating Patterns Time Limit:3000MS   Memory Limit:Unknown   64bit IO Format:%lld & %llu [Submit]  [Go Back]  [Status] Description The archaeologists are going to decipher a very mysterious ``language". Now, they know many language patterns; ea

hdu5384 AC自动机模板题,统计模式串在给定串中出现的个数

http://acm.hdu.edu.cn/showproblem.php?pid=5384 Problem Description Danganronpa is a video game franchise created and developed by Spike Chunsoft, the series' name is compounded from the Japanese words for "bullet" (dangan) and "refutation&q