• ZOJ3228


    题目大意

    给定一个文本串,接下来有n个模式串,每次查询模式串出现的次数,查询分两种,可重叠和不可重叠

    题解

    第一次是把AC自动机构造好,跑n次,统计出每个模式串出现的次数,交上去果断TLE。。。后来想想其实只要跑一次文本串即可。。。

    这个题目主要的问题是要解决有可重叠和不可重叠两种情况,用一个数组记录下模式串上一次出现的位置就可以判断是否重叠了

    代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <cstring>
    using namespace std;
    #define MAXN 100005
    const int maxnode=600005;
    const int sigma_size=26;
    char T[MAXN],s[7];
    bool flag[MAXN];
    int pos[MAXN];
    struct  Triegragh
    {
        int ch[maxnode][sigma_size];
        int fail[maxnode];
        int deep[maxnode];
        int cnt[maxnode][2];
        int end[maxnode];
        int last[maxnode];
        int val[maxnode];
        int sz;
        void init()
        {
            sz=1;
            memset(ch[0],0,sizeof(ch[0]));
            memset(cnt,0,sizeof(cnt));
            memset(end,-1,sizeof(end));
            memset(val,0,sizeof(val));
        }
        int idx(char c){return c-'a';}
        int insert(char *s)
        {
            int u=0,n=strlen(s);
            for(int i=0;i<n;i++)
            {
                int c=idx(s[i]);
                if(!ch[u][c])
                {
                    memset(ch[sz],0,sizeof(ch[sz]));
                    val[sz]=0;
                    deep[sz]=i+1;
                    ch[u][c]=sz++;
                }
                u=ch[u][c];
            }
            val[u]++;
            return u;
        }
        void getfail()
        {
            queue<int>q;
            fail[0]=0;
            for(int c=0;c<sigma_size;c++)
            {
                int u=ch[0][c];
                if(u){fail[u]=0;q.push(u);last[u]=0;} 
            }
            while(!q.empty())
            {
                int r=q.front();q.pop();
                for(int c=0;c<sigma_size;c++)
                {
                    int u=ch[r][c];
                    if(!u){ch[r][c]=ch[fail[r]][c];continue;}
                    q.push(u);
                    fail[u]=ch[fail[r]][c];
                    last[u]=val[fail[u]]?fail[u]:last[fail[u]];
                }
            }
        }
        void count(int j,int i)
        {
            if(j)
            {
                cnt[j][0]++;
                if(i-end[j]>=deep[j])
                {
                    cnt[j][1]++;
                    end[j]=i;
                }
                count(last[j],i);
            }
        }
        void find(char *T)
        {
            int j=0,n=strlen(T);
            for(int i=0;i<n;i++)
            {
                int c=idx(T[i]);
                j=ch[j][c];
                if(val[j])
                    count(j,i);
                else 
                    if(last[j]) count(last[j],i);
            }
        }
    };
    Triegragh ac;
    int main()
    {
        int kase=0; 
        while(scanf("%s",T)!=EOF)
        {
            printf("Case %d
    ",++kase);
            int n;
            scanf("%d",&n);
            ac.init();
            for(int i=1;i<=n;i++)
            {
                scanf("%d%s",&flag[i],s);
                pos[i]=ac.insert(s);
            }
            ac.getfail();
            ac.find(T);
            for(int i=1;i<=n;i++)
                printf("%d
    ",ac.cnt[pos[i]][flag[i]]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    什么是软件测试架构师?
    Spring常用注解
    Ant 风格路径表达式
    <url-pattern>写成/和/*的区别
    Spring+SpringMVC+Hibernate
    Spring+SpringMVC+MyBatis框架整合
    Spring各个jar包的介绍
    单点登录原理与简单实现(转载)
    博客网站系统
    POM.xml配置文件详解
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3341682.html
Copyright © 2020-2023  润新知