LightOJ 题目1427 - Substring Frequency (II)(AC自己主动机)

1427 - Substring Frequency (II)

PDF (English) Statistics Forum
Time Limit: 5 second(s) Memory Limit: 128 MB

A string is a finite sequence of symbols that are chosen from an alphabet. In this problem you are given a string T and n queries each with a string Pi, where the strings contain lower case English
alphabets only. You have to find the number of times Pi occurs as a substring of T.

Input

Input starts with an integer T (≤ 10), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 500). The next line contains the string T (1 ≤ |T| ≤ 106). Each of the next n lines contains a string Pi (1 ≤ |Pi|
≤ 500)
.

Output

For each case, print the case number in a single line first. Then for each string Pi, report the number of times it occurs as a substring of T in a single line.

Sample Input

Output for Sample Input


2

5

ababacbabc

aba

ba

ac

a

abc

3

lightoj

oj

light

lit


Case 1:

2

3

1

4

1

Case 2:

1

1

0

Notes

1.      Dataset is huge, use faster I/O methods.

2.       If S is a string then |S| denotes the length of S.

就是问子串在母串中的出现的次数(可重叠)

ac代码

#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
using namespace std;
const int  maxnode=250*1000+10000;
const int sg_size=26;
char str[1000100],key[550];
int pos[550];
struct Trie
{
    int ch[maxnode][sg_size];
    int val[maxnode];
    int f[maxnode];
    int num[maxnode];
    int sz;
    void init()
	{
		sz=1;
		memset(ch,0,sizeof(ch));
		memset(val,0,sizeof(val));
		memset(f,0,sizeof(f));
		memset(num,0,sizeof(num));
	}
    int idx(char c)
    {
        return c-‘a‘;
    }
    int insert(char *s)
    {
        int u=0,i;
        for(i=0;s[i];i++)
        {
            int c=idx(s[i]);
            if(!ch[u][c])
                ch[u][c]=sz++;;
            u=ch[u][c];
        }
        val[u]++;
        num[u]=0;
        return u;
    }
    void build_ac()
    {
        queue<int>q;
        int i;
        for(i=0;i<sg_size;i++)
        {
            if(ch[0][i])
                q.push(ch[0][i]);
        }
        int r,c,u,v;
        while(!q.empty())
        {
            r=q.front();
            q.pop();
            for(c=0;c<sg_size;c++)
            {
                u=ch[r][c];
                if(!u)
                    continue;
                q.push(u);
                v=f[r];
                while(v&&ch[v][c]==0)
                    v=f[v];
                f[u]=ch[v][c];
            }
        }
    }
    void find(char *s)
    {
        int j=0;
        for(int i=0;s[i];i++)
        {
            int c=idx(s[i]);
            while(j&&ch[j][c]==0)
                j=f[j];
            j=ch[j][c];
            int temp=j;
            while(temp)
            {
                num[temp]++;
                temp=f[temp];
            }
        }
    }
}ac;
int main()
{
	int t,c=0;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		scanf("%s",str);
		int i;
		ac.init();
		for(i=1;i<=n;i++)
		{
			scanf("%s",key);
			pos[i]=ac.insert(key);
		}
		ac.build_ac();
		ac.find(str);
		printf("Case %d:\n",++c);
		for(i=1;i<=n;i++)
		{
			printf("%d\n",ac.num[pos[i]]);
		}
	}
}
时间: 2024-11-02 18:13:43

LightOJ 题目1427 - Substring Frequency (II)(AC自己主动机)的相关文章

LightOJ 1427 Substring Frequency (II) (AC自动机)

题意:给定一个文本串和 n 个子串,问你子串在文本串出现的次数. 析:很明显的AC自动机,只要把先把子串进行失配处理,然后再去用文本串去匹配,在插入子串时就要标记每个串,注意串可能是相同的,这个我错了两次,最后匹配一次就OK了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib

Zoj 3535 Gao the String II (AC自己主动机+dp)

题目大意: 用集合A中的串构造出一个串,使之让很多其它的setB中的串成为他的子串. 思路分析: 和 Codeforces 86C 几乎相同. 只是这里是要用A中的构造. 先用A 和 B的串构造一个自己主动机.然后对于A集合的尾结点给出一个最大后缀匹配,对于B集合的尾结点给一个权值. dp[i][j][k] 表示已经构造出来了一个长度为i的串,如今走到了自己主动机的j结点.i长度后面有k个字符是没有匹配到的. 继续在自己主动机上走进行状态转移. if(isword >= k +1 )dp [i+

ZOJ 3494 BCD Code (AC自己主动机 + 数位DP)

题目链接:BCD Code 解析:n个病毒串.问给定区间上有多少个转换成BCD码后不包括病毒串的数. 很奇妙的题目. . 经典的 AC自己主动机 + 数位DP 的题目. 首先使用AC自己主动机,得到bcd[i][j]表示状态i,加了数字j以后到达的状态.为-1表示不能转移 然后就是数位DP了 注意记录为0的状态 AC代码: #include <cstdio> #include <iostream> #include <cstring> #include <algo

每日总结-05-19(AC自己主动机结束)

今天下午讨论了一下校赛的题,最终最终拍板,把校赛的题目定下来了. 然后今天A掉了4个AC自己主动机的题目.最终完毕了AC自己主动机专辑里面的15个题.至此AC自己主动机全然结束. 明天开启线段树专题. .... ------------------------------------------------------------------------------------------------------------------------------------ 1,,hdu-2457

【UVA】11468-Substring(AC自己主动机)

AC自己主动机的题,须要注意的,建立失配边的时候,假设结点1失配边连到的那个结点2,那个结点2是一个单词的结尾,那么这个结点1也须要标记成1(由于能够看成,这个结点包括了这个单词),之后在Trie树上进行行走,每次走到下一个能够走的结点. 14378527 11468 Substring Accepted C++ 0.585 2014-10-19 10:35:00 #include<cstdio> #include<cstring> #include<algorithm>

hdoj 2222 Keywords Search 【AC自己主动机 入门题】 【求目标串中出现了几个模式串】

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 44687    Accepted Submission(s): 14103 Problem Description In the modern time, Search engine came into the life of everybody li

ZOJ - 3228 Searching the String (AC自己主动机)

Description Little jay really hates to deal with string. But moondy likes it very much, and she's so mischievous that she often gives jay some dull problems related to string. And one day, moondy gave jay another problem, poor jay finally broke out a

HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)

题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP 用最短路预处理出状态的转移.能够优化非常多 AC代码: #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <queue> us

hdu 2825 Wireless Password(ac自己主动机&amp;amp;dp)

Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4022    Accepted Submission(s): 1196 Problem Description Liyuan lives in a old apartment. One day, he suddenly found that there