DataStructure

HDU-2896-病毒入侵(AC自动机)

2019-08-08  本文已影响0人  雨落八千里

病毒入侵

注意:这个病毒是ASCII码可见字符,不仅仅是小写字母。(卡了半天)

#include<bits/stdc++.h>
using namespace std;
const int M=101000;
int tree[M][128];
int num[M];
int fail[M];
char s[M];
int pos=1;
int vis[M];
priority_queue<int,vector<int>,greater<int> >q;
void insert(char *s,int cnt)
{
    int len=strlen(s);
    int root=0;
    for(int i=0;i<len;i++)
    {
        int x=s[i];
        if(!tree[root][x])
        {
            tree[root][x]=pos;
            pos++;
        }
        root=tree[root][x];
    }
    num[root]=cnt;//记录病毒序号
}
void getfail( )
{
    queue<int>qu;
    for(int i=0;i<128;i++)
    {
        if(tree[0][i])
        {
            fail[tree[0][i]]=0;
            qu.push(tree[0][i]);
        }
    }
    while(!qu.empty( ))
    {
        int u=qu.front( );
        qu.pop( );
        for(int i=0;i<128;i++)
        {
            if(tree[u][i])
            {
                fail[tree[u][i]]=tree[fail[u]][i];
                qu.push(tree[u][i]);
            }
            else
            {
                tree[u][i]=tree[fail[u]][i];
            }
        }
    }
}
void query(char *s)
{
    memset(vis,0,sizeof(vis));
    int len=strlen(s);
    int root=0;
    for(int i=0;i<len;i++)
    {
        int x=s[i];
        root=tree[root][x];
        for(int j=root;j&&num[j];j=fail[j])
        {
            if(vis[num[j]]==0)//防止病毒序号重复记录
            {
                q.push(num[j]);
                vis[num[j]]=1;
            }
            
        }
    }
}
int main( )
{
    int n,m,cnt=0;
    scanf("%d",&n);
    getchar( );
    while(n--)
    {
        cnt++;
        scanf("%s",s);
        insert(s,cnt);
    }
    fail[0]=0;
    getfail( );
    scanf("%d",&m);
    getchar( );
    cnt=0;
    int ans=0;
    while(m--)
    {
        cnt++;
        while(!q.empty( ))
        {
            q.pop( );
        }
        scanf("%s",s);
        query(s);
        if(!q.empty( ))
        {
            ans++;
            printf("web %d:",cnt);
            while(!q.empty( ))
            {
                printf(" %d",q.top( ));
                q.pop( );
            }
            printf("\n");
        }
    }
    printf("total: %d\n",ans);
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读