bzoj 3172 [Tjoi2013]单词(fail树,DP)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=3172
【题意】
题目的意思是这样的,给若干个单词,求每个单词在这一堆单词中的出现次数。 出题人语文水平高
【思路】
AC自动机. fail树
AC自动机中的fail指针指向该串的一个后缀,将fail指针反向后得到一棵fail树,利用getFail后的bfs序在树上进行DP统计出现次数。
在fail树上,父节点对应字符串是其子结点对应字符串的极大后缀。我们用sum[u]记录一个结点u被几个单词结点所经过,插入时顺便统计一下即可。设pos[i]为单词i在自动机上所对应的尾节点,那么这时候sum[pos[i]]是否为i的答案呢?不是。因为可能出现有一个字符串为abbabc,而i是abc的情况,这时候abc作为后缀出现但是并没有计数,对于结点u,我们应该将fail树上u->root路径上的所有节点的sum+=sum[u],这步操作只需要递推一下,这时候的sum[pos[i]]才是i的答案。
感觉与SAM中的p=>p->fa的思路挺像的。
【代码】
#include<cstdio>
#include<cstring>
using namespace std; const int N = 1e6+; struct ACauto {
int sz,ch[N][],sum[N],q[N],pos[N],f[N];
void init() {
sz=;
memset(ch[],,sizeof(ch[]));
}
void insert(char* s,int rank) {
int u=;
for(int i=;s[i];i++) {
int c=s[i]-'a';
if(!ch[u][c]) {
memset(ch[sz],,sizeof(ch[sz]));
ch[u][c]=sz++;
}
u=ch[u][c];
sum[u]++;
}
pos[rank]=u;
}
void get_Fail() {
int front=,rear=; //a pos for 0
f[]=; q[]=;
for(int i=,p;i<;i++)
if(p=ch[][i]) f[p]=,q[rear++]=p;
while(front!=rear) {
int qr=q[front++];
for(int c=;c<;c++) {
int u=ch[qr][c];
if(!u) continue;
q[rear++]=u; int v=f[qr];
while(v&&!ch[v][c]) v=f[v];
f[u]=ch[v][c];
}
}
for(int i=rear-;i>=;i--)
sum[f[q[i]]]+=sum[q[i]];
}
}ac; int n;
char s[N]; int main() {
scanf("%d",&n);
ac.init();
for(int i=;i<=n;i++) {
scanf("%s",s);
ac.insert(s,i);
}
ac.get_Fail();
for(int i=;i<=n;i++)
printf("%d\n",ac.sum[ac.pos[i]]);
return ;
}
bzoj 3172 [Tjoi2013]单词(fail树,DP)的更多相关文章
- bzoj 3172: [Tjoi2013]单词 fail树
题目大意: 一篇论文是由许多单词组成,现在想知道每个单词分别在论文中出现多少次. 题解: 我们首先考虑fail指针的含义 如果fail[x] = y,那么我们就知道y作为x的后缀在x中出现了一次 所以 ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ 3172([Tjoi2013]单词-后缀数组第一题+RMQ)
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 268 Solved: 145 [ Submit][ St ...
- bzoj 3172: [Tjoi2013]单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BZOJ 3172 [Tjoi2013]单词 AC自己主动机(fail树)
题意:链接 方法:AC自己主动机与fail树性质 解析:复习AC自己主动机的第一道题?(真正的第一题明明是又一次写了遍hdu2222! ) 这题说实话第一眼看上去就是个sb题,仅仅要建出来自己主动机. ...
- [BZOJ 3172] [Tjoi2013] 单词 【AC自动机】
题目链接:BZOJ - 3172 题目分析: 题目要求求出每个单词出现的次数,如果把每个单词都在AC自动机里直接跑一遍,复杂度会很高. 这里使用AC自动机的“副产品”——Fail树,Fail树的一个性 ...
- BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树
题目链接:[http://www.lydsy.com/JudgeOnline/problem.php?id=3172] 题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号 ...
- ●BZOJ 3172 [Tjoi2013]单词
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3172 题解: 把单词逐个接起来,中间用互不相同的字符连接,并记录下每个单词的首字母在串中的位 ...
- 【刷题】BZOJ 3172 [Tjoi2013]单词
Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N ...
随机推荐
- php四种基础排序算法的运行时间比较
/** * php四种基础排序算法的运行时间比较 * @authors Jesse (jesse152@163.com) * @date 2016-08-11 07:12:14 */ //冒泡排序法 ...
- MySQL基础学习之开始
学习MySQL数据库几个月了,从什么都不懂到现在这个地步,说实话感触很大,也感觉自己有许多不足之处.当接触MySQL的时候, 连创建一个数据表都想了很长的时间,不知道许多东西.幸亏我有一个好的老师,她 ...
- 【DB】SQLiteHelper
/// <summary> /// 说明:这是一个针对System.Data.SQLite的数据库常规操作封装的通用类. /// </summary> public class ...
- 关于《一步步学习ASP.NET MVC3》系列发布时间的说明
在写这个系列的时候,老魏也是下了很大的决心,因为平时基本上没有时间写文章,这回我要挑战我自己的意志力,决定要把这个系列写完整. 再次呢,老魏不能向大家保证什么时间结束,但基本上要保持一天一篇的进度,如 ...
- Emule使用Upnp,解决Lowid和port not reachable的问题
路由器上钩选开启Upnp Emule->选择->扩展选项->Upnp, 服务器:[从URL更新]http://upd.emule-security.org/server.met
- 当页面编辑或运行提交时,出现“从客户端中检测到有潜在危险的request.form值”问题,该怎么办呢?
最近在学习highcharts时,关于其中的导出功能,本来是想把导出的图片存放在本地,发现只有在电脑联网的情况下才可以一下导出图片,后来查阅了一番资料,才发现highcharts中的导出默认的官网服务 ...
- 对html进行SEO的一点点总结
1. 要考虑用户用哪些关键在查找您的网页 2. SE无法识别图形中的内容 3. 确保title和alt中的内容准确 4. 尽量用静态页,如果是动态页,参数要少 5. 每个图片都尽量用alt 6. 不用 ...
- 游戏文字自动断行需要,还得从 UTF-8 讲起
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码. UTF-8使用一至六个字节为每个字符编码(尽管如此,2 ...
- QStringRef可以提高性能,下次注意使用;QPair方便了语法,函数可以一次返回多个返回值,方便使用
而且QPair从此与各种QMap容器联系了起来,会非常好用.甚至QList也可以成双成对的使用元素了: QList<QPair<int, double> > list;list ...
- 【Linux安全】防止 root 用户远程登录
防止 root 用户远程登录,在终端输入以下命令: vim /etc/ssh/sshd_config 修改如下行为:no PermitRootLogin no 如图所示: