zoukankan      html  css  js  c++  java
  • 【BZOJ 3172】 [Tjoi2013]单词

    Description

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

    Input

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

    Output

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

    Sample Input

    3
    a
    aa
    aaa

    Sample Output

    6
    3
    1
     
    fail树的DP
    AC自动机的性质,fail指针指向的地方保证前缀相同,所以倒着跑DP就好了
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define ll long long 
     7 #define inf 1000000000
     8 #define mod 1000000007
     9 const int N=1000005;
    10 struct acm{
    11     int cnt;
    12     int next[1000005][26],sum[1000005],fail[1000005],q[1000005];
    13     char ch[1000005];
    14     acm(){
    15         cnt=1;
    16         for (int i=0;i<26;i++) next[0][i]=1;
    17     }
    18     void ins(int &pos){
    19         int now=1;
    20         scanf("%s",ch);
    21         int n=strlen(ch);
    22         for (int i=0;i<n;i++){
    23             if(!next[now][ch[i]-'a']) 
    24             next[now][ch[i]-'a']=++cnt;
    25             now=next[now][ch[i]-'a'];
    26             sum[now]++; 
    27         }
    28         pos=now;
    29     }
    30     void buildfail(){
    31         int head=0,tail=1;
    32         q[0]=1,fail[1]=0;
    33         while(head!=tail){
    34             int now=q[head];head++;
    35             for(int i=0;i<26;i++){
    36                 int v=next[now][i];
    37                 if(!v) continue;
    38                 int k=fail[now];
    39                 while(!next[k][i]) k=fail[k];
    40                 fail[v]=next[k][i];
    41                 q[tail++]=v;
    42             } 
    43         }
    44          for(int i=tail-1;i>=0;i--) 
    45             sum[fail[q[i]]]+=sum[q[i]];//就是这里啦!!!
    46     }
    47 }acm;
    48 int n,pos[N];
    49 int main(){
    50     scanf("%d",&n);
    51     for(int i=1;i<=n;i++) acm.ins(pos[i]);
    52     acm.buildfail();
    53     for (int i=1;i<=n;i++) printf("%d
    ",acm.sum[pos[i]]);
    54 }
  • 相关阅读:
    Java compiler level does not match the version of the installed Java project facet错误的解决
    java 面试 心得
    Oracle学习——第一章
    Window_Open详解
    在JSP页面获取集合的长度
    java实现文件上传
    Tcp与Ip协议的客户端和服务器编程
    异步委托
    同步委托最简单的一个列子
    使用多线程制作双色球
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5202607.html
Copyright © 2011-2022 走看看