社区讨论
为什么额外调用init()函数反而跑得更快
P5357【模板】AC 自动机参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @min8n63l
- 此快照首次捕获于
- 2025/12/01 22:22 3 个月前
- 此快照最后确认于
- 2025/12/03 22:05 3 个月前
rt, 38行在
insert() 里调用 init() 反而跑得快了 0.5 秒左右是什么玄学情况
#include <bits/stdc++.h>
template <typename T>inline void read(T& aim){T num=0,f=1;int ch=getchar();for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())num=num*10+ch-'0';aim=num*f;}
template <typename T>inline void write(T x){static int sta[40];int top=0;if(!x){putchar('0');return;}if(x<0)putchar('-'),x=-x;while(x)sta[++top]=x%10,x/=10;while(top)putchar(sta[top--]+'0');}
template <typename T>inline void print(T x,char ch='\n'){write(x);putchar(ch);}
inline void nl(){putchar('\n');}
template <typename T>inline void gmin(T& a,T b){if(a>b)a=b;}
template <typename T>inline void gmax(T& a,T b){if(a<b)a=b;}
template <typename T>inline T lowb(T x){return x&(-x);}
using namespace std;
typedef long long ll;
#define int long long
typedef pair<int,int> pii;
const int N=2e5+9,Sz=N;
namespace ac{
struct node{
int son[26],ans,fail,du,idx;
void init(){
memset(son,0,sizeof son);
ans=fail=idx=0;
}
}tr[Sz];
int tot,ans[N],pidx;
void init(){
tot=pidx=0;
tr[0].init();
}
void insert(char *s,int &idx){
int p=0;
for(int i=1;s[i];i++){
int &son=tr[p].son[s[i]-'a'];
if(!son)son=++tot,tr[son].init();//??faster
p=son;
}
if(!tr[p].idx)tr[p].idx=++pidx;
idx=tr[p].idx;
}
void build(){
queue<int>q;
for(int i=0;i<26;i++){
if(tr[0].son[i])q.push(tr[0].son[i]);
}
while(!q.empty()){
int x=q.front();q.pop();
for(int i=0;i<26;i++){
if(tr[x].son[i]){
tr[tr[x].son[i]].fail=tr[tr[x].fail].son[i];
tr[tr[tr[x].fail].son[i]].du++;
q.push(tr[x].son[i]);
}
else{
tr[x].son[i]=tr[tr[x].fail].son[i];
}
}
}
}
void query(char *s){
int p=0;
for(int i=1;s[i];i++){
p=tr[p].son[s[i]-'a'];
tr[p].ans++;
}
}
void topu(){
queue<int>q;
for(int i=0;i<=tot;i++){
if(tr[i].du==0)q.push(i);
}
while(!q.empty()){
int x=q.front();q.pop();
ans[tr[x].idx]=tr[x].ans;
int y=tr[x].fail;
tr[y].ans+=tr[x].ans;
if(!--tr[y].du)q.push(y);
}
}
}
int n,idx[N];
char s[N*10];
signed main(){
ac::init();
read(n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
ac::insert(s,idx[i]);
ac::ans[i]=0;
}
ac::build();
scanf("%s",s+1);
ac::query(s);
ac::topu();
for(int i=1;i<=n;i++){
print(ac::ans[idx[i]]);
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...