题目描述:

小张最近在忙毕设,所以一直在读论文。

一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次。

题解:

AC 自动机裸题,将所有字符串读入到一个数组里,字符串之间用 “#” 隔开即可。

Code:

#include<string>
#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
void setIO(string a){
freopen((a+".in").c_str(),"r",stdin);
} #define maxn 2000004
vector<int>G[maxn];
char arr[maxn],total[maxn];
int tag[maxn],ans[maxn],map[maxn],cnt=-1;
struct Automaton{
#define idx str[i]-'a'
#define root 0
#define sigma 27
int ch[maxn][sigma],last[maxn],fail[maxn],end[maxn];
int nodes;
int newnode(){ return ++nodes;} void insert(char str[],int id){
int n=strlen(str);
int pos=root;
for(int i=0;i<n;++i){
if(!ch[pos][idx]) ch[pos][idx]=newnode();
pos=ch[pos][idx];
}
G[pos].push_back(id);
end[pos]=1;
map[id]=pos;
} queue<int>Q;
void build(){
for(int i=0;i<sigma;++i) if(ch[root][i]) { Q.push(ch[root][i]),fail[ch[root][i]]=root; }
while(!Q.empty()){
int u=Q.front(); Q.pop();
for(int i=0;i<sigma;++i){
int r=ch[u][i];
if(!r) { ch[u][i]=ch[fail[u]][i]; continue; }
Q.push(r);
fail[r]=ch[fail[u]][i];
last[r]=end[fail[r]]? fail[r]: last[fail[r]];
}
}
} bool vis[maxn];
void print(int j){
while(j){
if(end[j]) tag[j]+=1;
j=last[j];
}
} void query(char str[]){
int j=root;
for(int i=0;i<cnt;++i){
if(str[i]=='#') j=root;
else
{
j=ch[j][idx];
print(j);
}
}
} }aho;
int main(){
//setIO("input");
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i) {
scanf("%s",arr), aho.insert(arr,i);
int cur_n=strlen(arr);
for(int j=0;j<cur_n;++j)
total[++cnt]=arr[j];
total[++cnt]='#';
++cnt;
}
aho.build();
aho.query(total);
for(int i=0;i<maxn;++i)
for(int j=0;j<G[i].size();++j) ans[G[i][j]]+=tag[i];
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
}

  

[TJOI2013]单词 AC 自动机的更多相关文章

  1. BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]

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

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

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

  3. bzoj 3172: [Tjoi2013]单词 AC自动机

    3172: [Tjoi2013]单词 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  4. 洛谷P3966 [TJOI2013]单词(AC自动机)

    题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...

  5. [TJOI2013]单词 AC自动机

    题面: 洛谷 题解: 很久之前做的题了,只不过之前一直90....最近才发现是哪里写错了. 我们对字符集建AC自动机. 首先考虑一个暴力的做法,把文章当做一个长串,直接在自动机上跳,但是我们会发现,这 ...

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

    关于AC自动机:一个在kmp与Trie的基础上建立的数据结构,关键在于Trie树结构与fail指针,他们各有各的应用.在AC自动机里最典型的就是多串匹配,原本效率为O(n*l+n*l+m*l),(n是 ...

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

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

  8. BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树

    题目链接:[http://www.lydsy.com/JudgeOnline/problem.php?id=3172] 题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号 ...

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

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

随机推荐

  1. nyoj--84--阶乘的0(数学技巧)

    阶乘的0 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 计算n!的十进制表示最后有多少个0 输入 第一行输入一个整数N表示测试数据的组数(1<=N<=100 ...

  2. (五)api网关服务 zuul-路由

    路由是微服务架构中必须的一部分,比如,“/” 可能映射到你的WEB程序上,”/api/users “可能映射到你的用户服务上,“/api/shop”可能映射到你的商品服务商.(注解:我理解这里的这几个 ...

  3. CreateProcess

    #include <Windows.h> //WINBASEAPI //BOOL //WINAPI //CreateProcessW( //_In_opt_ LPCWSTR lpAppli ...

  4. C#的常见算法(面试)(转)

    一.求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m //方法一,通过顺序规律写程序,同时也知道flag标志位的重要性. static int F1(int m) { ; ...

  5. sql server 更新满足条件的某一条记录

    上图数据:SNum为”18004XXXXX000001K2GW 4000 L1C“,OffLineStation为“OP1010”的有两条数据,当where条件中为上述两者时会同时更新这两条数据,并不 ...

  6. Windows 10 10586 升级

  7. java 实现多线程 3种方式

    java实现多线程可以有以下三种方式: (1)继承Thread 类,重写其run()方法: (2)实现Runnable接口,实现其run() 方法: (3) 实现Callable 接口,重写call( ...

  8. 安装lnmp前请先运行screen

    当通过putty或者SecureCRT安装lnmp时, 网络突然掉线或者不小心putty被关掉等等原因, 造成lnmp安装过程被中断怎么办? 其实防止这种现象很简单, 只要在安装lnmp前执行scre ...

  9. [codevs3955]最长严格上升子序列(加强版)

    题目大意:给你一个序列,要你求该序列中最长严格上升子序列的长度. 解题思路:此题算是一道LIS模板题.普通的$O(n^2)$的LIS是会TLE的,因为$n\le 1000000$,所以此题要用单调队列 ...

  10. python做的 QQ未读消息图像

    #!/usr/bin/pythonfrom PIL import Image ,ImageDraw, ImageFont#打开所在的文件im=Image.open('test.jpg')#获取图片对象 ...