HDU – 2222 Keywords Search AC自动机

ProLightsfx 2017-7-19 124 7/19

Keywords Search AC自动机

 Source

HDU - 2222

My Solution

题意:给出n个字符串为这些字符串在主串s中出现的个数。

AC自动机

裸的AC自动机,注意下给定模式串可能有一些相同的串,然后按照主串在自动机上遍历即可。

复杂度 O(n)

 

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
typedef long long LL;
const int CHAR_SIZE = 26;
const int MAX_SIZE = 5e5 + 8;
map<char, int> mp;

struct AC_Machine{
    int ch[MAX_SIZE][CHAR_SIZE], danger[MAX_SIZE], fail[MAX_SIZE];
    int sz;

    inline void init(){
        sz = 1;
        memset(ch[0], 0, sizeof ch[0]);
        memset(danger, 0, sizeof danger);
    }

    inline void _insert(const string &s){
        int n = s.size();
        int u = 0, c;
        for(int i = 0; i < n; i++){
            c = mp[s[i]];
            if(!ch[u][c]){
                memset(ch[sz], 0, sizeof ch[sz]);
                danger[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        danger[u]++;
    }

    inline void _build(){
        queue Q;
        fail[0] = 0;
        for(int c = 0, u; c < CHAR_SIZE; c++){
            u = ch[0][c];
            if(u){Q.push(u); fail[u] = 0;}
        }
        int r;
        while(!Q.empty()){
            r = Q.front();
            Q.pop();
            //danger[r] |= danger[fail[r]];
            for(int c = 0, u; c < CHAR_SIZE; c++){
                u = ch[r][c];
                if(!u){ch[r][c] = ch[fail[r]][c]; continue; }
                fail[u] = ch[fail[r]][c];
                Q.push(u);
            }
        }
    }
}ac;

string s;

int main()
{
    #ifdef LOCAL
    freopen("3.in", "r", stdin);
    //freopen("3.out", "w", stdout);
    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);
    int T, n, len, now, i, ans, tmp;
    for(int i = 0; i < 26; i++){mp[(i + 'a')] = i;} cin >> T;
    while(T--){
        cin >> n;
        ac.init();
        while(n--){
            cin >> s;
            ac._insert(s);
        }
        ac._build();

        cin >> s;
        ans = 0; len = s.size(); now = 0;
        for(i = 0; i < len; i++){
            now = ac.ch[now][mp[s[i]]];
            tmp = now;
            while(tmp){
                if(ac.danger[tmp]){
                    ans += ac.danger[tmp];
                    ac.danger[tmp] = 0;
                }
                tmp = ac.fail[tmp];
            }
        }
        cout << ans << "n";
    }
    return 0;
}

 

非特殊说明,本博所有文章均为博主原创,未经许可不得转载。

https://www.prolightsfxjh.com/

Thank you!

                                                                                                                                             ------from ProLightsfx

 

- THE END -

ProLightsfx

11月15日12:30

最后修改:2024年11月15日
0

非特殊说明,本博所有文章均为博主原创,未经许可不得转载。

共有 0 条评论