拓扑优化
- 优化目的:防止每次到一个点时就更新所有fail的点,大大节省时间
- 思路:在原来的模板上增加每个点的入度(有几个fail指针指着自己),在最后一次性更新(其实就是用fail指针建边的拓扑),新增内容详见代码
- 例题:洛谷 p5357
代码:
#include<bits/stdc++.h>
using namespace std;
struct tree{
int zz[27],fail,val,jl,rd;//rd为入度,jl为记录,记录走过此点的次数,用来统计单词数
}trie[200005];
char st[2000005];
int tot,ans=0,m[200005];//m位标记,m[i]=p 意为单词i的结尾在字典树的p位
void build(int l,int id)
{
int p=0;
for(int i=0;i<l;i++)
{
if(!trie[p].zz[st[i]-'a'])
{
trie[p].zz[st[i]-'a']=++tot;
}
p=trie[p].zz[st[i]-'a'];
}
trie[p].val=1;
m[id]=p;//结尾标记
}
void iflose()
{
int sj,sjs;
queue<int> q;
for(int i=0;i<26;i++)
{
if(trie[0].zz[i])
q.push(trie[0].zz[i]);
}
while(!q.empty())
{
sj=q.front();
q.pop();
for(int v,i=0;i<26;i++)
{
sjs=trie[sj].zz[i];
if(sjs==0)
continue;
v=trie[sj].fail;
while(v&&!trie[v].zz[i])v=trie[v].fail;
if(trie[v].zz[i]!=sjs)
{
trie[sjs].fail=trie[v].zz[i];
trie[trie[v].zz[i]].rd++; //增加入度
}
if(trie[sj].zz[i])
{
q.push(trie[sj].zz[i]);
}
}
}
}
void check()
{
int len=strlen(st),p=0;
for(int i=0;i<len;i++)
{
while(!trie[p].zz[st[i]-'a']&&p!=0)p=trie[p].fail;
p=trie[p].zz[st[i]-'a'];
if(!p)continue;
trie[p].jl++;
}
}
queue<int>q;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",st);
build(strlen(st),i);
}
iflose();
scanf("%s",st);
check();
for(int i=1;i<=tot;i++)
if(trie[i].rd==0)
q.push(i); //将所有入度为0的点压进栈
int sj;
while(!q.empty())
{
sj=q.front();q.pop();
trie[trie[sj].fail].jl+=trie[sj].jl;//给自己的失配指针所指的点x更新
trie[trie[sj].fail].rd--; //删去这条fail边
if(trie[trie[sj].fail].rd==0) //如果删后x入度为0
q.push(trie[sj].fail); //压入栈
}
for(int i=1;i<=n;i++)
printf("%d\n",trie[m[i]].jl);
return 0;
}
相关阅读
ROI的优化就像一场足球赛,需要根据市场条件,制定合理的战术布局,搭配不同的渠道,才能更大几率赢得比赛。ROI很重要。重要到,很多公司把
A5创业网(公众号:iadmin5)1月22日消息,近日,小米路由器下线了“自动重启”功能,被不少用户吐槽。小米路由器官方微博称,此次
享物说(小程序)作为一个好物互送的平台,越来越多的人在“单纯物品交换”环境下产生了很多互动。本文用HMW法分析,如何优化享物说这一
淘宝直通车是一个帮助在淘宝开店的商家们进行推广的一个工具,当然使用它是需要付费的,那么它到底有哪些功能呢?如何使用淘宝直通车
A5创业网(公众号:iadmin5)12月6日消息,最近斗鱼陷入了裁员风波。约70位斗鱼(香港)有限公司被公司裁员,斗鱼回应称正常的优化调整,但不