洛谷-3808 【模板】AC自动机(简单版)

本文详细介绍了Aho-Corasick算法的实现原理及应用,该算法是一种用于字符串匹配的高效算法,能够同时处理多个模式串在文本串中的搜索问题。文章通过具体的代码示例,展示了如何使用Aho-Corasick自动机进行模式串的插入、失败指针的构建以及文本串的查询过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
输入输出格式
输入格式:
第一行一个n,表示模式串个数;
下面n行每行一个模式串;
下面一行一个文本串。
输出格式:
一个数表示答案

输入输出样例
输入样例#1:
2
a
aa
aa

输出样例#1:
2

说明
subtask1[50pts]:∑length(模式串)<=106,length(文本串)<=106,n=1;
subtask2[50pts]:∑length(模式串)<=106,length(文本串)<=106

#include<bits/stdc++.h>
#define N 500010
using namespace std;
queue<int>q;
struct Aho_Corasick_Automaton{
    int c[N][26],val[N],fail[N],cnt;
    void ins(char *s){
        int len=strlen(s);int now=0;
        for(int i=0;i<len;i++){
            int v=s[i]-'a';
            if(!c[now][v])c[now][v]=++cnt;
            now=c[now][v];
        }
        val[now]++;
    }
    void build(){
        for(int i=0;i<26;i++)if(c[0][i])fail[c[0][i]]=0,q.push(c[0][i]);
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=0;i<26;i++)
            if(c[u][i])fail[c[u][i]]=c[fail[u]][i],q.push(c[u][i]);
            else c[u][i]=c[fail[u]][i];
        }
    }
    int query(char *s){
        int len=strlen(s);int now=0,ans=0;
        for(int i=0;i<len;i++){
            now=c[now][s[i]-'a'];
            for(int t=now;t&&~val[t];t=fail[t])ans+=val[t],val[t]=-1;
        }
        return ans;
    }
}AC;
int n;char p[1000005];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%s",p),AC.ins(p);
    AC.build();
    scanf("%s",p);int ans=AC.query(p);
    printf("%d\n",ans);
    return 0;
}
<think>好的,用户现在问的是关于3.4有没有学习路线,我需要先回顾之前的对话。之前用户问的是学习C++刷题和算法需要补充的知识点及优先级,我给出了详细的分类和排序。现在用户提到的“3.4”可能是指之前回复中的某个编号,比如第三部分第四点,或者可能是个排错误。 首先,检查之前的回复结构。之前的回答分为四个部分:一、C++核心知识点;二、算法与工程能力;三、优先级总排序;四、实践建议。在第三部分总排序中,列出了1到5点,但并没有3.4这样的编号。所以可能用户是误输入,或者“3.4”指其他内容,比如可能用户想询问学习路线的第三点第四部分,或者可能是个笔误。 考虑到用户之前的问题是关于学习路线,可能用户希望有一个更详细的学习阶段划分,比如分阶段的学习路线,比如3到4个月的计划,或者3个阶段、4个步骤之类的。也有可能“3.4”是用户引用之前回答的某个点,但原回答中没有这样的编号,所以可能是误解。 接下来,需要推测用户的真实需求。用户可能希望得到一个结构化的学习计划,分阶段或分步骤,帮助他们系统地学习C++和算法,以应对刷题和实际应用(如CV、搜广推、机器人等)。因此,需要构建一个分阶段的学习路线,结合之前的优先级排序,给出每个阶段的目标、内容和时间建议。 在构建学习路线时,需要平衡C++语言特性和算法数据结构的学习,同时结合实践项目和应用方向的不同侧重点。还要考虑用户可能的背景,比如是否已有基础,时间安排等,但用户没有提供这些信息,所以需要保持通用性。 可能需要将学习路线分为几个阶段,比如基础阶段、进阶阶段、应用阶段,每个阶段包含语言和算法两方面的内容,并给出每个阶段的时间建议和学习资源。同时,结合之前提到的知识点优先级,确保重要的内容先学。 另外,用户提到的应用方向(CV、搜广推、机器人)各有不同,可能需要在不同阶段加入针对性的学习内容。例如,CV需要数值计算和图像处理,机器人需要多线程和实时系统,搜广推需要设计模式和网络通信。 最后,需要确保学习路线清晰,步骤明确,并鼓励用户实践和项目应用,以巩固知识。同时,提醒用户根据自身情况调整进度,保持持续学习和实践。</think>以下是针对 **C++刷题(洛谷/力扣)** 和 **算法应用(CV/搜广推/机器人)** 的 **分阶段学习路线**,结合核心知识点优先级和实践建议,分为 **3个阶段+4个专项突破方向**,总计约3-4个月(可根据基础调整): --- ### **阶段1:基础夯实(1-1.5个月)** #### **目标**:掌握C++核心语法与基础算法,能解决力扣中等题。 1. **C++语法与STL(2周)** - **重点**: - 容器(`vector`/`unordered_map`/`priority_queue`)的底层原理与高频操作 - 算法(`sort`/`lower_bound`/`accumulate`)的灵活使用 - 迭代器与Lambda表达式(简化自定义比较逻辑) - **实践**:手写`vector`简化,理解动态扩容机制。 2. **基础算法与数据结构(3周)** - **必学内容**: - **算法**:二分查找、DFS/BFS、动态规划(背包/子序列)、贪心 - **数据结构**:链表、二叉树、哈希表、堆 - **刷题策略**: - 按「标签分类」刷题(如力扣“二叉树”专题),每天2-3题 - 优先解决高频题(如《剑指Offer》经典题)。 3. **调试与优化(1周)** - **工具**: - GDB调试段错误,Valgrind排查内存泄漏 - 时间复杂度分析(避免TLE) - **技巧**:用`chrono`库计时,对比不同算法的实际性能。 --- ### **阶段2:进阶突破(1-1.5个月)** #### **目标**:掌握高阶算法与工程能力,应对复杂场景。 1. **高阶算法(2周)** - **重点**: - 图论(最短路径/最小生成树) - 字符串处理(KMP/Trie树/AC自动机- 动态规划优化(状态压缩/斜率优化) - **刷题**:洛谷提高组题目、力扣Hard题(如[LC 312. 戳气球](https://leetcode.cn/problems/burst-balloons/))。 2. **C++进阶特性(2周)** - **必学**: - 模板与泛型编程(手写通用链表) - 多线程(`std::thread`/`std::mutex`) - 移动语义(右值引用/`std::move`) - **实践**:实现线程安全的队列模板,对比`std::move`与复制的性能差异。 3. **领域工具链(2周)** - **CV方向**:OpenCV基础(图像读写/滤波)、Eigen矩阵运算 - **机器人方向**:ROS基础通信模型、多线程实时控制 - **搜广推方向**:设计模式(工厂/观察者)、HTTP请求(`libcurl`)。 --- ### **阶段3:实战与专项(1-2个月)** #### **目标**:结合项目实战,深入特定领域。 1. **项目实战(3选1)** - **CV**:用C++实现图像边缘检测(Sobel算子) - **机器人**:模拟多传感器数据同步(线程+回调) - **搜广推**:实现简易LRU缓存(哈希表+双向链表)。 2. **竞赛与面试强化(1周)** - **技巧**: - 学习Codeforces/洛谷的输入输出加速技巧 - 掌握「代码模板化」思路(如快速排序非递归- **模拟面试**:限时解决力扣高频Hard题(如[LC 239. 滑动窗口最大值](https://leetcode.cn/problems/sliding-window-maximum/))。 --- ### **4个专项突破方向(可选)** 1. **并发编程**: - 学习`std::async`异步任务、原子操作(`std::atomic`) - 实战:用多线程加速归并排序。 2. **模板元编程**: - 掌握SFINAE、`constexpr`编译时计算 - 实战:实现编译期斐波那契数列。 3. **内存管理**: - 深入智能指针(`shared_ptr`控制块原理)、内存池设计 - 实战:手写简化内存池。 4. **算法优化**: - 学习SIMD指令集加速(如AVX2优化矩阵乘法) - 实战:对比普通循环与SIMD本的性能差异。 --- ### **学习资源推荐** 1. **书籍**: - 《算法导论》(理论) + 《挑战程序设计竞赛》(实战) - 《Effective C++》《C++并发编程实战》 2. **在线平台**: - 力扣(按标签刷题)、洛谷(模拟竞赛场景) - Codeforces(训练思维速度和代码容错性) 3. **开源项目**: - OpenCV源码(学习C++工程化设计) - LevelDB(理解STL风格的内存管理与数据结构)。 --- ### **关键原则** 1. **二八法则**:80%时间攻克高频考点(如动态规划、多线程),20%时间探索兴趣领域。 2. **反馈驱动**:每学完一个模块,用实际题目或项目验证效果(如学完DFS后刷岛屿问题)。 3. **领域交叉**:例如CV方向可将图像处理算法与C++多线程结合,提升实时性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值