zoukankan      html  css  js  c++  java
  • BZOJ 3172

    3172: [Tjoi2013]单词

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 3472  Solved: 1668
    [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

    AC自动机

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

    这题bzoj上我都能排进rank前50??

  • 相关阅读:
    常忘知识点一:嵌套属性
    button按钮的状态为disabled禁用状态,click事件无法触发,但是为什么touchstart下却依然可以触发
    shell
    sql help cs
    再次写给我们这些浮躁的程序员
    C# winform进度条 (异步)
    关于C# WinForm中进度条的实现方法
    Oracle 多行记录合并/连接/聚合字符串的几种方法
    PL/SQL编码规范的一些建议
    PL/SQL 日期时间类型函数及运算
  • 原文地址:https://www.cnblogs.com/fdfzhyf/p/6443475.html
Copyright © 2011-2022 走看看