zoukankan      html  css  js  c++  java
  • [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|1
    typedef 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
    ", 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]='';
    //        puts(buf);
    //        for(int i=0;i<ac.L;i++)
    //            printf("%d %d
    ", i, ac.end[i]);
            int ans=ac.query(buf);
            reverse(buf, buf+d);
            printf("%d
    ", ans+ac.query(buf));
        }
        return 0;
    }
    HDOJ 3695
  • 相关阅读:
    Linux快捷键、文件管理和查询
    Netty
    微软认知服务实现语音识别功能
    基础实用算法
    机器学习十大常用算法
    微服务之Swagger
    Quartz 入门详解 专题
    MyBatis(2):config.xml文件
    深入SpringBoot:自定义Endpoint
    快速掌握Flyway
  • 原文地址:https://www.cnblogs.com/Empress/p/4119869.html
Copyright © 2011-2022 走看看