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

    【题意】

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

    【分析】

          个人觉得是用了反fail树的思想,Ans[i]=t[i].cnt+∑Ans[反fail]...不过因为有些节点的反fail会有很多个,存起来不方便。但是AC自动机的fail却只有一个,而且我们在建立AC自动机的时候是用类似宽搜的方法建的,所以保存在队列里的节点肯定是由深到浅。然后我们就可以从后往前for一遍,把i的cnt加入到i的fail的cnt里,最后每个单词最末节点的cnt就是答案。

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 
     5 const int Maxn=(int)1e4;
     6 const int Maxl=200;
     7 
     8 struct node
     9 {
    10     int son[27],fail,cnt,ans;
    11 }t[16035707];
    12 
    13 int n,m,cnt=0;
    14 int q[Maxn*Maxl+10],bj[Maxn];
    15 char s[Maxl];
    16 
    17 void floy()
    18 {
    19     int i;
    20     for(i=1;i<=Maxn;i++) t[i].fail=0,t[i].ans=0;
    21 }
    22 
    23 void read() 
    24 {
    25      memset(bj,0,sizeof(bj));
    26      int i,j,x,ind;
    27      scanf("%d",&n);
    28      getchar();
    29      for(i=1;i<=n;i++)
    30      {
    31          scanf("%s",s+1);
    32          m=strlen(s+1);
    33          x=0;
    34          for(j=1;j<=m;j++)
    35          {
    36              ind=s[j]-'a'+1;
    37              if(!t[x].son[ind]) t[x].son[ind]=++cnt;
    38              x=t[x].son[ind];
    39              t[x].cnt++;
    40              if(j==m) bj[i]=cnt;
    41          }
    42      }
    43 }
    44 
    45 void Build_AC()
    46 {
    47     int i,x,y,j;
    48     q[0]=0;
    49     q[++q[0]]=0;
    50     //for(i=1;i<=26;i++)  if(t[0].son[i]) q[++q[0]]=t[0].son[i]; 
    51     for(i=1;i<=q[0];i++)
    52     {
    53         x=q[i];
    54         y=t[x].fail;
    55         for(j=1;j<=26;j++)
    56             if(t[x].son[j])   
    57             {                
    58                 //t[t[x].son[j]].fail=t[y].son[j];
    59                 t[t[x].son[j]].fail=x?t[y].son[j]:x; 
    60                 q[++q[0]]=t[x].son[j];   
    61             }
    62             else t[x].son[j]=t[y].son[j];
    63     }
    64     for(i=q[0];i>=1;i--)
    65     {
    66         t[t[q[i]].fail].cnt+=t[q[i]].cnt;
    67     }
    68 }
    69 
    70 int main()
    71 {
    72     read();
    73     Build_AC();
    74     for(int i=1;i<=n;i++) printf("%d
    ",t[bj[i]].cnt);
    75 }
    [BZOJ3172]

    2016-07-12 10:12:39

  • 相关阅读:
    三范式
    解决Linux下乱码
    ER概念模型
    20140607
    PHP Fatal error: Class 'Yaf_Application' not found
    PHP流式读取XML文件
    php反射的使用
    wget 和curl 进行post数据
    crontab
    Leetcode OJ: Gray Code
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5662552.html
Copyright © 2011-2022 走看看