【BZOJ3172】[TJOI2013] 单词(AC自动机的小应用)
大致题意: 给你\(N\)个单词,请你求出每一个单词在这\(N\)个单词中出现的次数。
相关题目
这道题应该是洛谷上一道板子题的升级版。
\(AC\)自动机
这是一道\(AC\)自动机的简单运用题。
题解
一个比较暴力的做法,就是将这\(N\)个单词建一棵\(Trie\),然后将每个单词一个一个分别去跑\(AC\)自动机,可惜这样子会\(TLE\)。
进一步的,我们可以发现,相同的单词跑\(AC\)自动机的结果是一样的,为什么不一起跑呢?
这样就可以\(AC\)了。
代码
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define tc() (A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++)
#define pc(ch) (pp_<100000?pp[pp_++]=ch:(fwrite(pp,1,100000,stdout),pp[(pp_=0)++]=ch))
#define N 200
#define SUM 1000000
int pp_=0;char ff[100000],*A=ff,*B=ff,pp[100000];
using namespace std;
int n,rt=1,tot=1,ans,s[N+5];
string ss[N+5];
struct Trie
{
int Son[26],Next,Cnt,Vis;
}node[SUM+5];
queue<int> q;
inline void read(int &x)
{
x=0;static char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-48,isdigit(ch=tc()));
}
inline void read_string(string &x)
{
x="";static char ch;
while(isspace(ch=tc()));
while(x+=ch,!isspace(ch=tc())) if(!(~ch)) return;
}
inline void write(int x)
{
if(x>9) write(x/10);
pc(x%10+'0');
}
inline void Insert(int pos,string st)
{
register int i,nxt,x=rt,len=st.length();
for(i=0;i<len;++i)
{
if(!node[x].Son[nxt=st[i]-97]) node[x].Son[nxt]=++tot;
x=node[x].Son[nxt];
}
++node[x].Cnt,s[pos]=x;
}
inline void GetNext()
{
register int i,k;q.push(rt);
while(!q.empty())
{
k=q.front(),q.pop();
for(i=0;i<26;++i)
{
if(k^rt)
{
if(!node[k].Son[i]) node[k].Son[i]=node[node[k].Next].Son[i];
else node[node[k].Son[i]].Next=node[node[k].Next].Son[i],q.push(node[k].Son[i]);
}
else
{
if(!node[k].Son[i]) node[k].Son[i]=rt;
else node[node[k].Son[i]].Next=rt,q.push(node[k].Son[i]);
}
}
}
}
inline void AC_Automation(string st,int val)//将字符串st作为文本串跑AC自动机,并用val记录st的重复个数
{
register int i,j,x=rt,len=st.length();
for(i=0;i<len;++i)
{
if(!(x=node[x].Son[st[i]-97])) {x=rt;continue;}
int p=x;
while(p^rt) node[p].Vis+=val,p=node[p].Next;//记录这个节点被val个字符串访问过了
}
}
int main()
{
register int i,j;
for(read(n),i=1;i<=n;++i) read_string(ss[i]),Insert(i,ss[i]);
for(GetNext(),i=1;i<=n;++i)
if(~node[s[i]].Cnt) AC_Automation(ss[i],node[s[i]].Cnt),node[s[i]].Cnt=-1;//一次性将所有与当前字符串相同的字符串一起跑AC自动机,并标记当前字符串已经跑过,不然会TLE
for(i=1;i<=n;++i) write(node[s[i]].Vis),pc('\n');//输出每一个字符串在Trie上所对应的节点被访问的次数
return fwrite(pp,1,pp_,stdout),0;
}
【BZOJ3172】[TJOI2013] 单词(AC自动机的小应用)的更多相关文章
- BZOJ3172[Tjoi2013]单词——AC自动机(fail树)
题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...
- bzoj3172: [Tjoi2013]单词 ac自动机
某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个单词 ...
- 【BZOJ3172】[Tjoi2013]单词 AC自动机
[BZOJ3172][Tjoi2013]单词 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- 洛谷P3966 [TJOI2013]单词(AC自动机)
题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...
- [TJOI2013]单词 AC自动机
题面: 洛谷 题解: 很久之前做的题了,只不过之前一直90....最近才发现是哪里写错了. 我们对字符集建AC自动机. 首先考虑一个暴力的做法,把文章当做一个长串,直接在自动机上跳,但是我们会发现,这 ...
- bzoj 3172: [Tjoi2013]单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- [TJOI2013]单词 AC 自动机
题目描述: 小张最近在忙毕设,所以一直在读论文. 一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 题解: AC 自动机裸题,将所有字符串读入 ...
- 【BZOJ-3172】单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2567 Solved: 1200[Submit][Status ...
- 【BZOJ 3172】[Tjoi2013]单词 AC自动机
关于AC自动机:一个在kmp与Trie的基础上建立的数据结构,关键在于Trie树结构与fail指针,他们各有各的应用.在AC自动机里最典型的就是多串匹配,原本效率为O(n*l+n*l+m*l),(n是 ...
随机推荐
- [Xcode 实际操作]四、常用控件-(14)使用UIWebView控件加载本地HTML
目录:[Swift]Xcode实际操作 本文将演示使用网页视图,加载并渲染网页代码. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit im ...
- 5、python数据类型之元组(tuple)
元组 元组和列表最大的区别是元组中的元素固定,元组不能修改,所以不能对元组进行增.删.改 1.创建 tu = (11,22,33) tu = tuple(11,22,33) tu = tuple([] ...
- 【JavaScript权威指南】——逻辑与(&&)
三种用法总结: 1.布尔值计算: [成员]={false,true} 2.“真值”,“假值”计算: [假值]={false,null,undefined,0,-0,NaN,""} ...
- HDU-2588-GCD (欧拉函数)
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the ...
- Nim && Grundy (基础博弈游戏 )
通常的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法 ...
- BeanFilterUtil
package com.yundaex.utility.bean.filter; import java.util.ArrayList; import java.util.List; import o ...
- Siverlight5 3D 中文环境搭建
一.测试环境 vs2010旗舰版 win7 64位旗舰版 二.必备工具 1.vs2010 旗舰版 2.vs2010 sp1 补丁 3.silverlight5 tools 也可以去silverligh ...
- SpringMVC10 InitBinder 注册自定义编辑器
1.配置web.xml文件 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3// ...
- c#异步Begininvoke使用随笔
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- java 整型相除得到浮点型
public class TestFloatOrDouble { public static void main(String[] args) { Point num1 = new Point(84, ...