【HDU2896】病毒侵袭(AC自动机)

来源:互联网 发布:vmware for ubuntu 编辑:程序博客网 时间:2024/05/01 14:35

记录一个菜逼的成长。。

题目链接
题目大意:
n个字符串,m个字符串,问m个字符串里每一个都包含了哪几种n个字符串里的。

跟上题类似,只不过这题有128个分支,把cnt数组用来记录n个字符串的编号,输出用优先队列维护。

#include <bits/stdc++.h>using namespace std;#define cl(a,b) memset(a,b,sizeof(a))typedef long long LL;const int INF = 0x3f3f3f3f;priority_queue<int,vector<int>,greater<int> >q;struct Trie{    int next[210*500][128],fail[210*500],cnt[210*500];    int root,L,id;    int newnode()    {        for(int i = 0;i < 128;i++)            next[L][i] = -1;        cnt[L++] = 0;        return L-1;    }    void init()    {        L = 0;id = 1;        root = newnode();    }    void Insert(char buf[])    {        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]];        }        cnt[now] = id++;    }    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];                    //这里不能够再清零了,因为有m个字符串,而不是只有一个。                    Q.push(next[now][i]);                }        }    }    void query(char buf[])    {        int len = strlen(buf);        int now = root;        for(int i = 0;i < len;i++)        {            now = next[now][buf[i]];            int temp = now;            while( temp != root )            {                if(cnt[temp])q.push(cnt[temp]);                temp = fail[temp];            }        }    }};const int maxn = 10000 + 10;char s[510][210],web[maxn];Trie ac;int main(){    int n;    while(~scanf("%d",&n)){        ac.init();        for( int i = 1; i <= n; i++ ){            scanf("%s",s[i]);            ac.Insert(s[i]);        }        ac.build();        int m,tot = 0,id = 0;scanf("%d",&m);        while(m--){            scanf("%s",web);            ac.query(web);            id++;            if(q.empty())continue;            tot++;            printf("web %d:",id);            while(!q.empty()){                printf(" %d",q.top());q.pop();            }            puts("");        }        printf("total: %d\n",tot);    }    return 0;}
0 0
原创粉丝点击