AC自动机加拓扑优化40分,求调!
查看原帖
AC自动机加拓扑优化40分,求调!
933706
realmayor楼主2023/6/22 00:54
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
string st[2005];
int ans[2005];
int ret[2005];
int tot = 0;
struct node
{
    int nex[26];
    int flag;
    int fail;
    int in;
    int end;
} nod[5000005];
void build(string &s, int num)
{
    int now = 0;
    int len = s.size() - 1;
    for (int i = 0; i <= len; i++)
    {
        if (!nod[now].nex[s[i] - 'a'])
        {
            nod[now].nex[s[i] - 'a'] = ++tot;
        }
        now = nod[now].nex[s[i] - 'a'];
    }
    if (!nod[now].flag)
    {
        nod[now].flag = now;
    }
    ans[num] = nod[now].flag;
}
void get_fail()
{
    queue<int> qe;
    for (int i = 0; i < 26; i++)
    {
        if (nod[0].nex[i])
        {
            qe.push(nod[0].nex[i]);
            nod[nod[0].nex[i]].fail = 0;
        }
    }
    while (!qe.empty())
    {
        int k = qe.front();
        qe.pop();
        for (int i = 0; i < 26; i++)
        {
            if (nod[k].nex[i])
            {
                nod[nod[k].nex[i]].fail = nod[nod[k].fail].nex[i];
                nod[nod[nod[k].fail].nex[i]].in++;
                qe.push(nod[k].nex[i]);
            }
            else
            {
                nod[k].nex[i] = nod[nod[k].fail].nex[i];
            }
        }
    }
}
void query(string &s)
{
    int now = 0;
    int len = s.size() - 1;
    for (int i = 0; i <= len; i++)
    {
        now = nod[now].nex[s[i] - 'a'];
        nod[now].end++;
    }
}
void tuopu()
{
    queue<int> qe;
    //  cout << tot << endl;
    for (int i = 1; i <= tot; i++)
    {
        if ((!nod[i].in) && nod[i].end)
        {
            qe.push(i);
        }
    }
    while (!qe.empty())
    {
        int k = qe.front();
        qe.pop();
        int temp = nod[k].fail;
        nod[temp].in--;
        if (!nod[temp].in)
        {
            qe.push(temp);
        }
        nod[temp].end += nod[k].end;
        // cout << nod[temp].end << endl;
        ret[nod[k].flag] += nod[k].end;
    }
}
signed main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> st[i];
        build(st[i], i);
    }
    get_fail();
    for (int i = 1; i <= n; i++)
    {
        query(st[i]);
    }
    tuopu();
    for (int i = 1; i <= n; i++)
    {
        // cout << ans[i] << endl;
        cout << ret[ans[i]] << endl;
    }
}
2023/6/22 00:54
加载中...