【bzoj3172】: [Tjoi2013]单词

先用所有单词构造一个AC自动机

题目要求的是每个单词在这个AC自动机里匹配到的次数

每次insert一个单词的时候把路径上的cnt++

那么点p->cnt就是以root到p这条路径为前缀的单词的个数

如果p->fail指向了点q,那么就会对q点产生p->cnt的贡献(root到q一定为root到p的后缀)

最后递推统计完所有fail的贡献,找到关键点输出就可以了

 /* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; struct trie{
trie *next[],*fail;
int cnt,x;
}t[]; int n;
char s[];
trie *root,*NEW=t;
trie *Q[],*wh[]; trie *new1(int x){NEW++; NEW->cnt=; NEW->x=x; return NEW;} trie *insert(trie *p,int x){
if (!p->next[x]) p->next[x]=new1(x);
p->next[x]->cnt++;
return p->next[x];
} #define pnf p->next[i]->fail
void build_fail(){
int l=,r=;
for (int i=;i<;i++) if (root->next[i]) { Q[++r]=root->next[i]; root->next[i]->fail=root;}
while (l!=r){
trie *p=Q[++l];
for (int i=;i<;i++){
if (p->next[i]){
Q[++r]=p->next[i];
for (pnf=p->fail ; pnf!=root && !pnf->next[i] ; pnf=pnf->fail);
if (pnf->next[i]) pnf=pnf->next[i];
}
}
}
for (int i=r;i>=;i--) Q[i]->fail->cnt+=Q[i]->cnt;
} int main(){
scanf("%d",&n);
root=new1(-);
for (int i=;i<=n;i++){
scanf("%s",s);
wh[i]=root;
int l=strlen(s);
for (int j=;j<l;j++) wh[i]=insert(wh[i],s[j]-'a');
}
build_fail();
for (int i=;i<=n;i++) printf("%d\n",wh[i]->cnt);
return ;
}

一开始zz把strlen放到循环里慢了十几倍

【bzoj3172】: [Tjoi2013]单词 字符串-AC自动机的更多相关文章

  1. BZOJ3172 [Tjoi2013]单词 【AC自动机】

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 4293  Solved: 2083 [Submit][Stat ...

  2. bzoj千题计划315:bzoj3172: [Tjoi2013]单词(AC自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3172 构建AC自动机 在fail树上,点i的子树大小 表示trie树上根节点到i构成的单词 是 多 ...

  3. [BZOJ3172 ][Tjoi2013]单词(AC自动机)

    Description 不稳定的传送门 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次.单词个数<=200,单词总长度< ...

  4. 【BZOJ3172】单词(AC自动机)

    [BZOJ3172]单词(AC自动机) 题面 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input ...

  5. 【BZOJ3172】[TJOI2013] 单词(AC自动机的小应用)

    点此看题面 大致题意: 给你\(N\)个单词,请你求出每一个单词在这\(N\)个单词中出现的次数. 相关题目 这道题应该是洛谷上一道板子题的升级版. \(AC\)自动机 这是一道\(AC\)自动机的简 ...

  6. BZOJ3172 [Tjoi2013]单词 字符串 SA ST表

    原文链接http://www.cnblogs.com/zhouzhendong/p/9026543.html 题目传送门 - BZOJ3172 题意 输入$n(n\leq 200)$个字符串,保证长度 ...

  7. [BZOJ 3172] [Tjoi2013] 单词 【AC自动机】

    题目链接:BZOJ - 3172 题目分析: 题目要求求出每个单词出现的次数,如果把每个单词都在AC自动机里直接跑一遍,复杂度会很高. 这里使用AC自动机的“副产品”——Fail树,Fail树的一个性 ...

  8. 【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】

    P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...

  9. bzoj 3172: [Tjoi2013]单词【AC自动机】

    一眼AC自动机,就是先把串建一个自动机,标记每个串在自动机上的位置,然后加上间隔符连成一个串在自动机上跑,每跑到一个点就说明这个串以及它到root的所有点表示的串都要被更新一次 先在点上打上标记,最后 ...

随机推荐

  1. bash 中的行处理命令 awk

    转自:http://blog.chinaunix.net/uid-23302288-id-3785105.html

  2. 杂项:C# 方法、属性杂项-01

    ylbtech-杂项:C# 方法.属性杂项-01 1. 属性杂项返回顶部 1. public int ReadCnt { get; set; } 2.设置默认值 public int ReadCnt ...

  3. 分布式代码管理github

    Git是世界上最先进的分布式版本的控制系统,特点是:简单大气上档次. Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了.

  4. altium designer 中器件原理图库中,将一个器件分成几部分是如何操作的?就是如何用part表示?

    在SCH Library的Components中选中你要添加part的器件,tools菜单--new part即可

  5. Git 之Windows环境下学习系列

    Git .SVN .TFS   相同点 不同点 Git     版本控制 优点: 分布式版本控制.无需联网就能版本提交 开源 缺点 入门学习难度高 SVN   优点: 集中式版本控制. 个人开源 缺点 ...

  6. 使用pip一次升级所有安装的Python包(太牛了)

    import pip from subprocess import call for dist in pip.get_installed_distributions(): call("pip ...

  7. 记录下Linux难记实用的命令

    看文件大小:du -sm * | sort -n 合并多个文件,可以跨文件夹合并:cat *_.txt >> news.txt 给文件改编码:iconv -f GBK -t UTF-8 原 ...

  8. LaTeX 控制图片的位置

    加感叹号来忽略“美学”标准. \begin{figure}[!htb] \usepackage{float}\begin{figure}[H]插到你代码相应的位置. 1,插入并列的子图 \usepac ...

  9. adb pull 和 adb push

    1. 操作单个文件 通过adb push,则可将文件添加到SD卡中.如果想在push的时候修改文件名称的话,只需要修改push的第二个参数改成完整路径(目录+文件名),如/sdcard/test-0. ...

  10. LinkedHashMap和HashMap的区别

    一.问题描述: 前几天写webservices接口,需要同步人力资源,涉及到添加顺序:主账号需要添加在次账号之前,直接上级需要添加在下级之前.解析xml之后直接封装在HashMap中,导致取对象时顺序 ...