有木有大佬来解释一下AC自动机的小疑惑?
  • 板块学术版
  • 楼主Demon_master
  • 当前回复8
  • 已保存回复8
  • 发布时间2022/8/2 16:46
  • 上次更新2023/10/27 17:20:58
查看原帖
有木有大佬来解释一下AC自动机的小疑惑?
544446
Demon_master楼主2022/8/2 16:46
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn =5e6+5;
inline ll read_int(){
    ll a=0,f=0,g=getchar();
    while(g<'0'||g>'9'){if(g=='-') f=1;g=getchar();}
    while('0'<=g&&g<='9') a=(a << 3) + (a << 1) + (g ^ 48),g=getchar();
    return f ? -a : a;
}
inline void write(ll s,bool f=1){
    ll top=0,a[40];
    if(s<0) s=-s,putchar('-');
    while(s) a[++top]=s%10,s/=10;
    if(top==0) a[++top]=0;
    while(top) putchar(a[top]+'0'),top--;
    if(f) putchar('\n');
}

int n;
int tree[maxn][27],cnt=1;
#define getnum(a) ((a)-('a'))
char lin[maxn];
int jl[maxn],nex[maxn];

inline void insert(char s[]){
    int l=strlen(s+1);
    int u=1;
    for(int i=1;i<=l;i++){
        if(!tree[u][getnum(s[i])]) tree[u][getnum(s[i])]=++cnt;
        u=tree[u][getnum(s[i])];
    }
    jl[u]++;
}

inline void build(){
    for(int i=0;i<=25;i++) tree[0][i]=1;
    nex[1]=0;
    queue<int> p;
    p.push(1);
    while(!p.empty()){
        int u=p.front();
        p.pop();
        for(int i=0;i<=25;i++){
            if(!tree[u][i]) tree[u][i]=tree[nex[u]][i];
            else{
                nex[tree[u][i]]=tree[nex[u]][i];
                p.push(tree[u][i]);
            }
        }
    }
}

inline int search(char a[]){
    int ans=0;
    int u=1;
    int l=strlen(a+1);
    for(int i=1;i<=l;i++){
        int k=tree[u][getnum(a[i])];
        while(k>1&&jl[k]){
            if(jl[k]){
                ans+=jl[k];
                jl[k]=0;
            }
            k=nex[k];
        }
        u=tree[u][getnum(a[i])];
    }
    return ans;
}

inline void read(){
    n=read_int();
    for(int i=1;i<=n;i++) scanf("%s",lin+1),insert(lin);
    build();
    scanf("%s",lin+1);
    write(search(lin));
}

int main (){
    // freopen("P3808_1.in","r",stdin);
    read();
    while(1) getchar();
}

在这一段代码中,如果不加&&jl[k]则会卡死 求为什么(最好有例子)

inline int search(char a[]){
    int ans=0;
    int u=1;
    int l=strlen(a+1);
    for(int i=1;i<=l;i++){
        int k=tree[u][getnum(a[i])];
        while(k>1&&jl[k]){
            if(jl[k]){
                ans+=jl[k];
                jl[k]=0;
            }
            k=nex[k];
        }
        u=tree[u][getnum(a[i])];
    }
    return ans;
}

谢谢

2022/8/2 16:46
加载中...