bzoj3172【TJOI2013】单词
2016-01-05 23:41
393 查看
3172: [Tjoi2013]单词
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2178 Solved: 1012
[Submit][Status][Discuss]
Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。Input
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6Output
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。Sample Input
3a
aa
aaa
Sample Output
63
1
HINT
Source
AC自动机+递推,思路很好(详见程序)#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define ll long long #define pa pair<int,int> #define maxn 1000005 #define inf 1000000000 using namespace std; int n,tot=1,cnt=0,t[maxn][26],go[maxn],w[maxn],a[maxn],p[205]; bool v[maxn]; char s[maxn]; queue<int> q; inline void bfs() { q.push(1); while (!q.empty()) { int x=q.front(),y,j;q.pop();v[x]|=v[go[x]]; a[++cnt]=x;//a数组是按bfs顺序生成的 F(i,0,25) { j=go[x]; while (j&&!t[j][i]) j=go[j]; if (t[x][i]) { go[y=t[x][i]]=j?t[j][i]:1; q.push(y); } else t[x][i]=j?t[j][i]:1; } } } int main() { scanf("%d",&n); F(i,1,n) { scanf("%s",s); int len=strlen(s),now=1; F(j,0,len-1) { int x=s[j]-'a'; if (!t[now][x]) t[now][x]=++tot; now=t[now][x]; w[now]++; } p[i]=now;//p数组记录了每个单词结尾节点的位置 } bfs(); D(i,cnt,1) w[go[a[i]]]+=w[a[i]];//这里计算答案的方法很巧妙,相当于按bfs的反方向递推 F(i,1,n) printf("%d\n",w[p[i]]);//这里只要输出w[p[i]]就可以了 return 0; }
相关文章推荐
- xsl与xml转换示例
- Meteor:关闭所有tab时退出登录
- lesson1:Python 判断表达式应用
- maven是什么?(转自oracle官网)
- Java延迟初始化的2种经典模式
- Spark MLlib 包
- mysql 5.7 忘记密码,及修改密码问题,密码列不再是Password ,而是authentication_string
- UITableView的简单使用
- 单个电脑上进行多ssh-key配置
- RDD容错
- svnversion 不是内部命令或外部命令,也不是可运行的程序或批处理文件
- 让手机访问电脑的tomcat
- 数据库006
- SQL学习(二)
- 数据库之基础6
- RDD类操作说明
- Latex宏包管理
- Latex宏包管理
- Latex宏包管理
- Latex宏包管理