传送门

做了这么多题怎么还是无法很好的理解AC自动机呢..果然是个制杖

首先题意表述不是很清晰,这些所有的单词组成了那个文章,所以果断建个AC自动机,建的时候给每个点附加一个权值,建树是经过一次权值即+1。

然后根据建立fail的轨迹,其实就是Trie树的bfs序。根据这个逆序。对于每个点fail指向的点,把那个店的权值累加上当前点的权值。然后输出就行了。

建树的时候初始累加的权值也就是整篇文章有多少个独立的单词,然后每个fail指针指向词一定是在当前的词里出现过。所以就把被指向的点的权值加上当前点的权值。

//BZOJ 3172
//by Cydiater
//2016.10.21
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <cstdio>
using namespace std;
#define ll long long
#define up(i,j,n)		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
const int MAXN=1e6+5;
const int oo=0x3f3f3f3f;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
char s[MAXN];
int sum[MAXN],next[MAXN][26],fail[MAXN],N,LEN,cnt=0,now,end[MAXN],q[MAXN],head,tail;
namespace solution{
	void insert(){
		now=0;
		up(i,1,LEN){
			if(!next[now][s[i]-'a'])next[now][s[i]-'a']=++cnt;
			now=next[now][s[i]-'a'];sum[now]++;
		}
	}
	void init(){
		N=read();
		up(i,1,N){
			scanf("%s",s+1);
			LEN=strlen(s+1);
			insert();end[i]=now;
		}
	}
	void buildAC(){
		head=1;tail=0;up(i,0,25)if(next[0][i])q[++tail]=next[0][i];
		for(;head<=tail;head++){
			int node=q[head];
			up(i,0,25){
				int son=next[node][i];
				if(!son)next[node][i]=next[fail[node]][i];
				else{
					fail[son]=next[fail[node]][i];
					q[++tail]=son;
				}
			}
		}
	}
	void slove(){
		down(head,tail,1)sum[fail[q[head]]]+=sum[q[head]];
	}
	void output(){
		up(i,1,N)printf("%d\n",sum[end[i]]);
	}
}
int main(){
	//freopen("input.in","r",stdin);
	using namespace solution;
	init();
	buildAC();
	slove();
	output();
	return 0;
}

BZOJ3172: [Tjoi2013]单词的更多相关文章

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

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

  2. [Bzoj3172][Tjoi2013]单词(fail树)

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 4777  Solved: 2345[Submit][Status ...

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

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

  4. BZOJ3172——[Tjoi2013]单词

    1. 题目大意:一篇论文是由许多单词组成,现在想知道每个单词分别在论文中出现多少次. 2.分析:对着 广义后缀自动机的图看,我们就会发现玄机,答案不就是这个单词下的后缀个数吗? 于是建立自动机,然后求 ...

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

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

  6. BZOJ3172[Tjoi2013]单词——AC自动机(fail树)

    题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...

  7. bzoj3172: [Tjoi2013]单词 ac自动机

    某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个单词 ...

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

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

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

    fail图上后缀和需要注意一下 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整 ...

随机推荐

  1. TNS-12541: TNS:no listener TNS-12560 TNS-00511: No listener

        为了测试需要,系统管理员帮忙将一台ORACLE数据库服务器克隆到虚拟机上,我上去删除了root.oracle.tomcat账号下的crontab定时作业,然后启动了ORACLE数据库实例,删除 ...

  2. 记一道有意思的算法题Rotate Image(旋转图像)

    题出自https://leetcode.com/problems/rotate-image/ 内容为: You are given an n x n 2D matrix representing an ...

  3. CentOS7minimal MySql的卸载及安装

    因为CentOS7精简版默认是有残留的MySql的,所以开始时一定要先卸载掉原来的MySql 首先要使用root用户登录 卸载: 1.卸载原有程序 yum remove mysql mysql-ser ...

  4. C++基础——函数指针 函数指针数组

    ==================================声明================================== 本文版权归作者所有. 本文原创,转载必须在正文中显要地注明 ...

  5. Unity贴图锯齿

    之前在做一个Unity视频插件,发现渲染上去的贴图锯齿十分明显,开了抗锯齿也没用.最后在一次偶然的机会,发现了原来是贴图FilterMode设置有问题 之前用的是FilterMode.Point,后来 ...

  6. Android使用HttpURLConnection通过POST方式发送java序列化对象

    使用HttpURLConnection类不仅可以向WebService发送字符串,还可以发送序列化的java对象,实现Android手机和服务器之间的数据交互. Android端代码: public ...

  7. Android 通过Uri获取Bitmap对象

    (转自:http://blog.sina.com.cn/s/blog_5de73d0b0100zfm8.html) private Bitmap getBitmapFromUri(Uri uri) { ...

  8. shell数值运算与运算符

  9. Netruon 理解(11):使用 NAT 将 Linux network namespace 连接外网

    学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...

  10. struts2的拦截器(Interceptor)与过滤器(Filter)

    一.拦截器与过滤器的区别: 1.filter基于回调函数,我们需要实现的filter接口中doFilter方法就是回调函数,而interceptor则基于Java本身的反射机制,这是两者最本质的区别. ...