P3966 [TJOI2013]单词

时间:2022-12-03 22:39:01

P3966 [TJOI2013]单词

题目描述

小张最近在忙毕设,所以一直在读论文。一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次。

输入输出格式

输入格式:

第一行一个整数N,表示有N个单词。接下来N行每行一个单词,每个单词都由小写字母(a-z)组成。(N≤200)

输出格式:

输出N个整数,第i行的数表示第i个单词在文章中出现了多少次。

输入输出样例

输入样例#1:
3
a
aa
aaa
输出样例#1:
6
3
1

说明

数据范围

30%的数据, 单词总长度不超过10^3

100%的数据,单词总长度不超过10^6

看上去题目貌似很简单,不就是把trie树一建然后对每个单词跑一遍AC自动机吗?然而这样会被卡死,考虑如何来优化,由于题目中说每一个单词会多次出现,那么我们就可以统计一下每个单词出现的次数,把这个出现次数看做这个单词的权值,然后在跑AC自动机时直接把这个权值加入到答案中,那么我们如何处理重复出现的单词并统计次数呢?其实我们在trie树上就可以搞定,如果两个单词相同,那么他们在trie树上的结束节点一定相同,这样就可以进行统计了。

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<vector>
#define maxn 1050005
using namespace std; inline int read()
{
char c=getchar();
int res=,x=;
while(c<''||c>'')
{
if(c=='-')
x=-;
c=getchar();
}
while(c>=''&&c<='')
{
res=res*+(c-'');
c=getchar();
}
return res*x;
} int n,tot=;
int tree[maxn][],nt[maxn],bo[maxn],ed[maxn],f[maxn],t[maxn];
char a[][maxn];
queue<int>q; void trie(char *s,int num)
{
int len=strlen(s),u=;
for(register int i=;i<len;i++)
{
int c=s[i]-'a';
if(!tree[u][c])
{
tree[u][c]=++tot;
}
u=tree[u][c];
}
if(bo[u])
t[num]=;//t数组表示这个单词之前是否出现过
bo[u]++;
ed[num]=u;
} void bfs()
{
for(register int i=;i<;i++)
{
tree[][i]=;
}
nt[]=;q.push();
while(q.size())
{
int u=q.front();q.pop();
for(register int i=;i<;i++)
{
if(!tree[u][i])
tree[u][i]=tree[nt[u]][i];
else
{
int v=tree[u][i];
q.push(v);
nt[v]=tree[nt[u]][i];
}
}
}
} void find(char *s,int num)
{
int len=strlen(s),u=,k,ans=bo[ed[num]];//ans表示这个单词出现的次数
for(register int i=;i<len;i++)
{
int c=s[i]-'a';
k=tree[u][c];
while(k>)
{
if(bo[k])
f[k]+=ans;
k=nt[k];
}
u=tree[u][c];
}
} int main()
{
n=read();
for(register int i=;i<=n;i++)
{
scanf("%s",a[i]);
trie(a[i],i);
}
bfs();
for(register int i=;i<=n;i++)
{
if(!t[i])//这里我们只需要将每个不重复出现的单词跑一边AC自动机
find(a[i],i);
}
for(register int i=;i<=n;i++)
{
printf("%d\n",f[ed[i]]);
}
return ;
}

P3966 [TJOI2013]单词的更多相关文章

  1. 洛谷P3966 &lbrack;TJOI2013&rsqb;单词(fail树性质)

    P3966 [TJOI2013]单词 题目链接:https://www.luogu.org/problemnew/show/P3966 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单 ...

  2. 洛谷P3966 &lbrack;TJOI2013&rsqb;单词&lpar;AC自动机&rpar;

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

  3. 洛谷P3966 &lbrack;TJOI2013&rsqb;单词(后缀自动机)

    传送门 统计单词出现次数……为啥大家都是写AC自动机的嘞……明明后缀自动机也能做的说…… 统计出现次数这个就直接按长度排序然后做个dp就好,这是SAM的板子的要求啊,不提了 然后考虑怎么让所有串之间隔 ...

  4. Luogu P3966 &lbrack;TJOI2013&rsqb;单词

    题目链接 \(Click\) \(Here\) 本题\(AC\)自动机写法的正解之一是\(Fail\)树上跑\(DP\). \(AC\)自动机是\(Trie\)树和\(Fail\)树共存的结构,前者可 ...

  5. &lbrack;洛谷P3966&rsqb;&lbrack;TJOI2013&rsqb;单词

    题目大意:有$n$个字符串,求每个字符串在所有字符串中出现的次数 题解:$AC$自动机,每个节点被经过时$sz$加一,每一个字符串出现次数为其$fail$树子树$sz$和 卡点:$AC$自动机根节点为 ...

  6. 【洛谷】3966:&lbrack;TJOI2013&rsqb;单词【AC自动机】【fail树】

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

  7. BZOJ 3172&colon; &lbrack;Tjoi2013&rsqb;单词 &lbrack;AC自动机 Fail树&rsqb;

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

  8. 【BZOJ3172】&lbrack;Tjoi2013&rsqb;单词 AC自动机

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

  9. 3172&colon; &lbrack;Tjoi2013&rsqb;单词

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

随机推荐

  1. Database 'xxx' cannot be upgraded because it is read-only or has read-only file Make the database or files writeable&comma; and rerun recovery&period;

      在分离数据库DatabaseName(暂且用DatabaseName代替该数据库名)后,我将其数据文件以及日志文件移动到新增的磁盘上.然后附加该数据库,结果报如下错误: Database 'Dat ...

  2. mysql的故事

    所有的条件都分开理解,命令之间没有包含吗?

  3. 插件二之页面加载进度条pace&period;js

    关于pace.js pace.js包含14样式,每种样式可以自定义颜色,官方下载中提供了几种颜色的主题,使用方式也很简单,引入pace的js文件跟所需样式文件即可 <link rel=&quot ...

  4. jquery 请求apache solr 跨域解决方案

    <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script&gt ...

  5. 【20】宁以pass-by-reference-to-const替换pass-by-value

    1.首先理解需求,被调用方法修改了形参,如果期望在主调方法中的实参也发生变化,必须使用pass-by-reference.因为C++缺省情况下(继承C方式),以by-value传递对象,在被调方法中修 ...

  6. 【protobuf进阶】读取proto实体里的extensionObject对象的方法

    //设置扩展对象 ProtoBuf.Extensible.AppendValue //读取扩展对象 ProtoBuf.Extensible.GetValue 最近通过C#的TcpClient调用jav ...

  7. servlet 之 返回json数据并显示

    //实体类import java.util.ArrayList; public class ObjectType { private String type; private ArrayList&lt ...

  8. TD中&lbrace;text-overflow&colon;ellipsis&semi;&rcub; 用法

    Styles: table{ table-layout:fixed; } table td{ text-overflow:ellipsis;overflow:hidden;white-space: n ...

  9. EXEC 和 SP&lowbar;EXECUTESQL的区别

    摘要: MSSQL为我们提供了两种动态执行sql语句的命令:EXEC 和 SP_EXECUTESQL.通常SP_EXECUTESQL更具优势,因为它提供了输入输出的接口,且能够重用执行计划,大大提高执 ...

  10. switch&lowbar;root vs pivot&lowbar;root vs chroot【转】

    1. pivot_root can/should be used together with chroot pivot_root new_root put_old pivot_root moves t ...