绿 掉 绿掉 绿掉 的 代 码 的代码 的代码
敲 简 单 的 , 康 康 代 码 吧 ! 敲简单的,康康代码吧! 敲简单的,康康代码吧!
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct Trie_Tree{
ll fail;
ll child[27];//每父节点下的子节点有26个(26个字母)※child[]表示当前访问的节点
ll end;//标记有几个单词以这个节点结尾
}ac[1000000 + 10];
ll cnt = 0;//Trie的指针
inline void Build(string mushichuan){//建树
ll l = mushichuan.length();
ll now = 0;//访问字典树的当前位置
for(ll i = 0; i < l; i++){//构造Trie树
if(ac[now].child[mushichuan[i] - 'a'] == 0)//树没这个节点, s[i] - 'a' 把对应的字母变成数字
ac[now].child[mushichuan[i] - 'a'] = ++cnt;//如 "A B C" 需要构造三层,每一层都事先把 a~z 26个字母打好
now = ac[now].child[mushichuan[i] - 'a'];//往下递归
}//最后跳出循环需把单词结尾标记一下
ac[now].end++;
}
void get_fail(){//构造fail指针
queue <ll> q;
for(ll i = 0; i <= 26; i++){//初始条件
if(ac[0].child[i] != 0){//构造了此节点, ac[0] 表示根节点
ac[ac[0].child[i]].fail = 0;//先把所有的第二层节点都指向根节点
q.push(ac[0].child[i]);//把根节点的子节点 push 进 queue 中
}
}
while(!q.empty()){//bfs求每一相同的字符串,再将fail指针指向相同字符串的子节点
ll father = q.front();
q.pop();
for(ll i = 0; i < 26; i++){
if(ac[father].child[i] != 0){//父节点下存在子节点
ac[ac[father].child[i]].fail = ac[ac[father].fail].child[i];//看图解
q.push(ac[father].child[i]);//像第一层把父节点的子节点 push 进 queue 中
}
else//父节点下不存在子节点
ac[father].child[i] = ac[ac[father].fail].child[i];//虚根(看图解)
}
}
}
ll AC_COUT(string wenbenchuan){//自动AC机的匹配
ll l = wenbenchuan.length();
ll now = 0, ans = 0;//now = 0 先从根结点出发
for(ll i = 0; i< l; i++){
now = ac[now].child[wenbenchuan[i] - 'a'];//向下走, s[i] - 'a' 把对应的字母变成数字
for(ll next = now; next && ac[next].end != -1; next = ac[next].fail){//下一个节点没有 || 没有访问过, 循环求解
ans += ac[next].end;//计算单词节点(看图解)
ac[next].end = -1;//与上方对应,就不会重复使用
}
}
return ans;
}
int main(){
ll n;
string mushichuan, wenbenchuan;
cin >> n;
for(ll i = 1; i <= n; i++){
cin >> mushichuan;
Build(mushichuan);//建树
}
ac[0].fail = 0;//根节点的 fail 指针指向 0(结束标志)
get_fail();//构造fail指针
cin >> wenbenchuan;
cout << AC_COUT(wenbenchuan) << endl;
return 0;
}
希 望 大 家 多 多 提 出 宝 贵 的 意 见 ! 希望大家多多提出宝贵的意见! 希望大家多多提出宝贵的意见!
既
然
你
耐
心
看
完
了
这
篇
题
解
,
何
不
如
既然你耐心看完了这篇题解,何不如
既然你耐心看完了这篇题解,何不如一键三连
再
走
呢
?
T
h
a
n
k
s
♪
(
・
ω
・
)
ノ
(
再走呢?Thanks♪(・ω・)ノ(
再走呢?Thanks♪(・ω・)ノ(B
站
看
多
了
[
复
杂
]
)
站看多了[复杂])
站看多了[复杂])