hdu2896-ac自动机

来源:互联网 发布:淘宝七乐康药店 假货 编辑:程序博客网 时间:2024/05/24 03:07

这个加入了记录编号

就是把原来的那个记录次数的改成记录标号

不要忘记每一次init

不要忘记build

不要忘记数组开的大小

直接查询的话,是不能保证按照原来顺序的,所以找到所有答案之后应该再排一下顺序

#include <iostream>#include <cstdio>#include <queue>#include <algorithm>#include <cstring>using namespace std;const int MAX=220*500;int cnt;struct Trie{    int next[MAX][128],fail[MAX],end[MAX],bh[MAX];    int root,L;    int newnode()    {        for (int i=0;i<128;i++)            next[L][i]=-1;        end[L++]=0;        return L-1;    }    void init()    {        L=0;        cnt=0;        memset(bh,0,sizeof(bh));        root=newnode();    }    void insert(char *buf)    {        cnt++;        int len=strlen(buf);        int now=root;        for (int i=0;i<len;i++)        {            if (next[now][buf[i]]==-1)                next[now][buf[i]]=newnode();            now=next[now][buf[i]];        }        bh[now]=cnt;        end[now]++;    }    void build ()    {        queue<int >Q;        fail[root]=root;        for (int i=0;i<128;i++)            if (next[root][i]==-1)                next[root][i]=root;            else            {                fail[next[root][i]]=root;                Q.push(next[root][i]);            }        while (!Q.empty())        {            int now=Q.front();            Q.pop();            for (int i=0;i<128;i++)                if (next[now][i]==-1)                    next[now][i]=next[fail[now]][i];                else                {                    fail[next[now][i]]=next[fail[now]][i];                    Q.push(next[now][i]);                }        }    }    int query(char *buf)    {        int len=strlen(buf);        int now=root;        int res=0;        for (int i=0;i<len;i++)        {            now=next[now][buf[i]];            int temp=now;            while (temp!=root)            {                res+=end[temp];                //end[temp]=0;                temp=fail[temp];            }        }        return res;    }    void query_(char *buf)    {        int len=strlen(buf);        int ans[501];        int cn=0;        int now=root;        for (int i=0;i<len;i++)        {            now=next[now][buf[i]];            int temp=now;            while (temp!=root)            {                if (bh[temp])                {                    cn++;                    ans[cn]=bh[temp];                }                temp=fail[temp];            }        }        sort(ans+1,ans+cn+1);        for (int i=1;i<=cn;i++)            printf(" %d",ans[i]);    }};char buf[10005];Trie ac;int main(){    int n,m;    while (scanf("%d",&n)==1)    {        ac.init();        for (int i=0;i<n;i++)        {            scanf("%s",buf);            ac.insert(buf);        }        cin>>m;        ac.build();        int ans=0;        for (int i=1;i<=m;i++)        {            scanf("%s",buf);            if (ac.query(buf))            {                ans++;                printf("web %d:",i);                ac.query_(buf);                printf("\n");            }        }        printf("total: %d\n",ans);    }    return 0;}


0 0
原创粉丝点击