首页 > 代码库 > [AC自动机]HDOJ3695 Computer Virus on Planet Pandora

[AC自动机]HDOJ3695 Computer Virus on Planet Pandora

题意:给t、n,t个案例,n个字符串

  下面给n+1个字符串,n个互不相同的小串,最后一个是模式串

  模式串会出现[qx]的形式,q为数字,x为一个字母

问n个小串在模式串中出现的个数,正着出现、反着出现都算。

 

蛮裸的ac自动机,本来想着在query里面把找到过的end清零,把模式串展开正着反着找两遍,那即使再找到加零也不影响。但是超时了。。。

于是把找到过的end标为-1,-1了就不再找下去,就可以了~上代码

 

#include <cstdio>#include <cstdlib>#include <cstring>#include <climits>#include <cctype>#include <cmath>#include <string>#include <sstream>#include <iostream>#include <algorithm>#include <iomanip>using namespace std;#include <queue>#include <stack>#include <vector>#include <deque>#include <set>#include <map>typedef long long LL;typedef long double LD;const double eps=1e-8;#define pi acos(-1.0)#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1typedef pair<int, int> PI;typedef pair<int, PI> PP;#ifdef _WIN32#define LLD "%I64d"#else#define LLD "%lld"#endif//#pragma comment(linker, "/STACK:1024000000,1024000000")//LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans*=a;a=a*a;b>>=1;}return ans;}//inline int read(){char ch=‘ ‘;int ans=0;while(ch<‘0‘ || ch>‘9‘)ch=getchar();while(ch<=‘9‘ && ch>=‘0‘){ans=ans*10+ch-‘0‘;ch=getchar();}return ans;}//inline void print(LL x){printf(LLD, x);puts("");}//inline void read(double &x){char c = getchar();while(c < ‘0‘) c = getchar();x = c - ‘0‘; c = getchar();while(c >= ‘0‘){x = x * 10 + (c - ‘0‘); c = getchar();}}//inline void sc(LL &x){scanf(LLD, &x);}struct Trie{    int next[5000100][26], fail[5000100], end[5000100];    int root, L;    int newnode()    {        for(int i=0;i<26;i++)            next[L][i]=-1;        end[L++]=0;        return L-1;    }    void init()    {        L=0;        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]-A]==-1)                next[now][buf[i]-A]=newnode();            now=next[now][buf[i]-A];        }        end[now]++;    }    void build()    {        queue<int> Q;        fail[root]=root;        for(int i=0;i<26;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<26;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]-A];            int tmp=now;            while(tmp!=root && end[tmp]!=-1)            {                res+=end[tmp];         //printf("%d %d\n", tmp, end[tmp]);                end[tmp]=-1;                tmp=fail[tmp];            }        }        return res;    }}ac;char buf[5200010], tmp[5200010];int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);    freopen("out.txt", "w", stdout);#endif    int T;    scanf("%d", &T);    while(T--)    {        int n;        scanf("%d", &n);        ac.init();        for(int i=0;i<n;i++)        {            scanf("%s", buf);            ac.insert(buf);//            int LEN=strlen(buf);//            reverse(buf, buf+LEN);//            ac.insert(buf);        }        ac.build();        scanf("%s", tmp);        int LEN=strlen(tmp), d=0;        for(int i=0;i<LEN;i++)            if(tmp[i]==[)            {                int cur=i+1, num=0;                while(isdigit(tmp[cur]))                    num=num*10+tmp[cur++]-0;                fill(buf+d, buf+d+num, tmp[cur]);                i=cur+1, d+=num;            }            else                buf[d++]=tmp[i];        buf[d]=\0;//        puts(buf);//        for(int i=0;i<ac.L;i++)//            printf("%d %d\n", i, ac.end[i]);        int ans=ac.query(buf);        reverse(buf, buf+d);        printf("%d\n", ans+ac.query(buf));    }    return 0;}
HDOJ 3695

 

[AC自动机]HDOJ3695 Computer Virus on Planet Pandora