zoukankan      html  css  js  c++  java
  • bzoj3172 [Tjoi2013]单词

    Description

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

    Input

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

    Output

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

    Sample Input

    3
    a
    aa
    aaa

    Sample Output

    6
    3
    1

    正解:$AC$自动机。

    $AC$自动机板子题。刚刚复习了一下,基本上还记得,只是$last$数组那里忘了,不过这题也不需要。。

    直接构出$trie$树和$fail$树,然后按照$fail$树自底向上更新单词数量就行了。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <complex>
     5 #include <cstring>
     6 #include <cstdlib>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cmath>
    10 #include <queue>
    11 #include <stack>
    12 #include <map>
    13 #include <set>
    14 #define inf (1<<30)
    15 #define N (1000010)
    16 #define il inline
    17 #define RG register
    18 #define ll long long
    19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    20 
    21 using namespace std;
    22 
    23 int q[N],pos[210],n,len;
    24 char s[N];
    25 
    26 struct AC_auto{
    27 
    28     int ch[N][26],val[N],nxt[N],last[N],sz;
    29     
    30     il void insert(char *s,RG int len,RG int p){
    31     RG int x=0,c;
    32     for (RG int i=1;i<=len;++i){
    33         c=s[i]-97; if (!ch[x][c]) ch[x][c]=++sz;
    34         x=ch[x][c],val[x]++;
    35     }
    36     pos[p]=x; return;
    37     }
    38     
    39     il void build(){
    40     RG int h=0,t=0;
    41     for (RG int c=0;c<26;++c)
    42         if (ch[0][c]) nxt[ch[0][c]]=last[ch[0][c]]=0,q[++t]=ch[0][c];
    43     while (h<t){
    44         RG int x=q[++h],v,j;
    45         for (RG int c=0;c<26;++c){
    46         v=ch[x][c];
    47         if (!v){ ch[x][c]=ch[nxt[x]][c]; continue; }
    48         q[++t]=v,j=nxt[x]; while (j && !ch[j][c]) j=nxt[j];
    49         nxt[v]=ch[j][c],last[v]=val[nxt[v]] ? nxt[v] : last[nxt[v]];
    50         }
    51     }
    52     for (RG int i=t;i;--i) val[nxt[q[i]]]+=val[q[i]]; return;
    53     }
    54     
    55 }AC;
    56 
    57 il int gi(){
    58     RG int x=0,q=1; RG char ch=getchar();
    59     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    60     if (ch=='-') q=-1,ch=getchar();
    61     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    62     return q*x;
    63 }
    64 
    65 il void work(){
    66     n=gi();
    67     for (RG int i=1;i<=n;++i){
    68     scanf("%s",s+1),len=strlen(s+1);
    69     AC.insert(s,len,i);
    70     }
    71     AC.build();
    72     for (RG int i=1;i<=n;++i)
    73     printf("%d
    ",AC.val[pos[i]]);
    74     return;
    75 }
    76 
    77 int main(){
    78     File("word");
    79     work();
    80     return 0;
    81 }
  • 相关阅读:
    scp 一个最简单的Linux 数据copy
    ORA-65096: invalid common user or role 解决方法
    SQL Server 查询 数据库 & 表格 大小
    SQL Server 配置 Job 监控 tempdb 变化
    SQL Server 邮箱告警配置
    浅谈 SQL Server 中的等待类型(Wait Type)
    Oracle 常用命令大全(持续更新)
    连接Oracle 12c R2 报错ORA-28040:No matching authentication protocal
    Oracle 数据库启动和关闭
    SQL Server 日志收缩方法
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6702528.html
Copyright © 2011-2022 走看看