字符串BZOJ上面几个AC自动机求最为字串出现次数的题目

Posted hua-dong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串BZOJ上面几个AC自动机求最为字串出现次数的题目相关的知识,希望对你有一定的参考价值。

(一下只供自己复习用,目的是对比这几个题,所以写得不详细。需要细节的可以参考其他博主)

【BZOJ3172:单词】

题目:

         某人读论文,一篇论文是由许多(N)单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。N<=200,总单词长度不超过10^6。

思路:

        简单题,建立AC自动机,插入的时候每个位置都++,代表以当前位置为后缀的字符串的个数,用于fail转移时累加。然后build得到fail指针;最后从叶子向根累加。

技术分享图片
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000010;
char c[maxn]; int ans[maxn],pos[210],N;
struct Trie
{
    int ch[maxn][26],cnt,times,fail[maxn],q[maxn],head,tail;
    Trie(){ cnt=times=head=tail=0; }
    int insert(){
        int Now=0,L=strlen(c+1);
        for(int i=1;i<=L;i++){
            if(!ch[Now][c[i]-a]) ch[Now][c[i]-a]=++cnt;
            Now=ch[Now][c[i]-a];
            ans[Now]++;
        }
        return Now;
    }
    void build()
    {
        for(int i=0;i<26;i++)
          if(ch[0][i]) q[++head]=ch[0][i];
        while(tail<head){
            int Now=q[++tail];
            for(int i=0;i<26;i++){
                if(ch[Now][i]){
                    fail[ch[Now][i]]=ch[fail[Now]][i];
                    q[++head]=ch[Now][i];
                }
                else ch[Now][i]=ch[fail[Now]][i];
            }        
        }
        for(int i=tail;i>=1;i--) ans[fail[q[i]]]+=ans[q[i]];
    } 
}T;
int main()
{
    scanf("%d",&N);
    for(int i=1;i<=N;i++){
        scanf("%s",c+1);
        pos[i]=T.insert();
    }
    T.build(); 
    for(int i=1;i<=N;i++) printf("%d\n",ans[pos[i]]);
    return 0;
}
View Code

 

【BZOJ2434阿狸的打字机】:

题目:

          给定N个字符串。现在又Q个问题,每次问题给出(i,j),求第i个字符串在第j个字符串里出现的次数。 1<=N<=10e5;1<=M<=10e5;输入总长<=10e5

思路:

         因为上一题是单次讯问,而且是整体求,所以一次拓扑倒序累加即可,但是此题是多次询问,而且是针对Trie树上代表的两个字符串之间的包含次数,不能整体法。 正解: 1,先建立AC自动机;2,得到fail树;3,对fail树进行DFS得到DFS序;4,在Trie树上dfs求解。

 【BZOJ3881】
  题意:
         Bob有个字符串集合T,一开始为空,现在有两种操作:1,Bob的集合新增加一个字符串str; 2,Alice给出字符串x,问集合T中多少字符串包含x。1e6级别。
 
 

以上是关于字符串BZOJ上面几个AC自动机求最为字串出现次数的题目的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ3172][TJOI2013]单词 AC自动机

bzoj1444 有趣的游戏(AC自动机+概率dp)

BZOJ3172: [Tjoi2013]单词

LA_4670_Dominating_Patterns_(AC自动机+map)

BZOJ 2434 [Noi2011]阿狸的打字机(AC自动机)

[JSOI2007]文本生成器(AC自动机+DP)