C++之路进阶——bzoj3172(单词)

F.A.QsHomeDiscussProblemSetStatusRanklistContestModifyUser   hyxzcLogout捐赠本站
Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入、输出语句及数据类型及范围,避免无谓的RE出现。

3172: [Tjoi2013]单词

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 2218  Solved: 1033
[Submit][Status][Discuss]

Description

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

Input

第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6

Output

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

Sample Input

3
a
aa
aaa

Sample Output

6
3
1

HINT

 

Source

题解:

     只是裸题而已.....

    初步使用结构体算法。。。

    hzwer伴我成长

代码:

   

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 int n,pos[1000005];
 9 struct acm
10    {
11     int sz,point[1000005],q[1000005],sum[1000005],a[1000005][26];
12     char ch[1000005];
13     acm()
14     {sz=1;for (int i=1;i<=26;i++) a[0][i]=1;}
15         
16        void insert(int &pos)
17           {
18           scanf("%s",ch);
19                 int now=1;
20                 for (int i=0;i<strlen(ch);i++)
21                      {
22                           int t=ch[i]-'a'+1;
23                        if (a[now][t]) now=a[now][t];
24                             else now=a[now][t]=++sz;
25                             sum[now]++;
26                       }
27                 pos=now;
28            } 
29        
30        void acmach()
31           {
32                 int w=1,t=0;
33                 point[1]=0,q[0]=1; 
34                 while (t<w)
35                    {
36                        int now=q[t++];
37                        for (int i=1;i<=26;i++)
38                      {
39                          if (!a[now][i]) continue;
40                          int k=point[now];
41                          while (!a[k][i])k=point[k];
42                          point[a[now][i]]=a[k][i];
43                          q[w++]=a[now][i];
44                          }    
45                    }
46           for (int i=t-1;i>=0;i--)
47               {
48                   sum[point[q[i]]]+=sum[q[i]];
49                          }           
50           }
51        
52    }acm;
53    
54 int main()
55    {
56         scanf("%d",&n);
57         for (int i=1;i<=n;i++)
58            acm.insert(pos[i]);
59         acm.acmach();
60         for (int i=1;i<=n;i++)
61           printf("%d\n",acm.sum[pos[i]]);
62        }    

 

   

转载于:https://www.cnblogs.com/grhyxzc/p/5150673.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值