• HDU 3065 病毒侵袭持续中 | AC自动机


    原题链接

    //中文题好感动啊!!!


    题解:

    比较裸的AC自动机吧,对所有模式串建个AC自动机之后

    用网站源码在上面跑匹配.

    注意AC自动机建的时候字符集是26就好,遇到源码中别的字符直接回到Root

    每个结尾节点记个CNT,我也不知道不记会不会跪

    还有!注意这是个多组数据

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define Z 27
    #define M 2000010
    using namespace std;
    struct node
    {
        int ch[Z],id,fail,cnt;
        void clear()
    	{
    	    memset(ch,0,sizeof(ch));
    	    cnt=id=fail=0;
    	}
    }t[50010];
    int n,cnt[1010],tot=1;
    char s[1010][60],text[M];
    void insert(int id)
    {
        int p=1,len=strlen(s[id]);
        for (int i=0;i<len;i++)
        {
    	if (t[p].ch[s[id][i]-'A']==0)
    	    t[t[p].ch[s[id][i]-'A']=++tot].clear();
    	p=t[p].ch[s[id][i]-'A'];
        }
        t[p].id=id;
        t[p].cnt++;
    }
    void BuildFail()
    {
        queue <int> q;
        t[1].fail=1;
        for (int i=0;i<26;i++)
    	if (t[1].ch[i]==0)
    	    t[1].ch[i]=1;
    	else
    	    t[t[1].ch[i]].fail=1,q.push(t[1].ch[i]);
        while (!q.empty())
        {
    	int u=q.front(),v,w;
    	for (int i=0;i<26;i++)
    	{
    	    v=t[t[u].fail].ch[i],w=t[u].ch[i];
    	    if (w) t[w].fail=v,q.push(w);
    	    else t[u].ch[i]=v;
    	}
    	q.pop();
        }
    }
    void query(char s[])
    {
        int len=strlen(s),p=1;
        for (int i=0;i<len;i++)
        {
    	if (s[i]>'Z' || s[i]<'A')
    	{
    	    p=1;
    	    continue;
    	}
    	p=t[p].ch[s[i]-'A'];
    	if (t[p].id!=0)
    	    cnt[t[p].id]+=t[p].cnt;
        }
    }
    void init()
    {
        memset(cnt,0,sizeof(cnt));
        t[1].clear();
        tot=1;
    }
    int main()
    {
        while (scanf("%d",&n)!=EOF)
        {
    	init();
    	for (int i=1;i<=n;i++)
    	    scanf("%s",s[i]),insert(i);
    	BuildFail();
    	getchar();
    	gets(text);
    	query(text);
    	for (int i=1;i<=n;i++)
    	    if (cnt[i]>0)
    		printf("%s: %d
    ",s[i],cnt[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    忆2011年的秋天:一个人的项目
    横看成岭侧成峰,远近高低各不同——从面试官的角度谈面试
    使用Scratch进行少儿编程
    初识少儿编程
    升级openssl
    CentOS设置虚拟网卡做NAT方式和Bridge方式桥接
    iptables conntrack有什么用
    nohup和&的区别
    Linux就这个范儿 第12章 一个网络一个世界
    一个由INode节点爆满引起的业务故障
  • 原文地址:https://www.cnblogs.com/mrsheep/p/7989228.html
Copyright © 2020-2023  润新知