zoukankan      html  css  js  c++  java
  • 【bzoj3172】: [Tjoi2013]单词 字符串-AC自动机

    【bzoj3172】: [Tjoi2013]单词

    先用所有单词构造一个AC自动机

    题目要求的是每个单词在这个AC自动机里匹配到的次数

    每次insert一个单词的时候把路径上的cnt++

    那么点p->cnt就是以root到p这条路径为前缀的单词的个数

    如果p->fail指向了点q,那么就会对q点产生p->cnt的贡献(root到q一定为root到p的后缀)

    最后递推统计完所有fail的贡献,找到关键点输出就可以了

     1 /* http://www.cnblogs.com/karl07/ */
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <algorithm>
     7 using namespace std;
     8 
     9 struct trie{
    10     trie *next[26],*fail;
    11     int cnt,x;
    12 }t[1000005];
    13 
    14 int n;
    15 char s[1000005];
    16 trie *root,*NEW=t;
    17 trie *Q[1000005],*wh[300];
    18 
    19 trie *new1(int x){NEW++; NEW->cnt=0; NEW->x=x; return NEW;}
    20 
    21 trie *insert(trie *p,int x){
    22     if (!p->next[x]) p->next[x]=new1(x);
    23     p->next[x]->cnt++;
    24     return p->next[x];
    25 }
    26 
    27 #define pnf p->next[i]->fail
    28 void build_fail(){
    29     int l=0,r=0;
    30     for (int i=0;i<26;i++) if (root->next[i]) { Q[++r]=root->next[i]; root->next[i]->fail=root;}
    31     while (l!=r){
    32         trie *p=Q[++l];
    33         for (int i=0;i<26;i++){
    34             if (p->next[i]){
    35                 Q[++r]=p->next[i];
    36                 for (pnf=p->fail ; pnf!=root && !pnf->next[i] ; pnf=pnf->fail);
    37                 if (pnf->next[i]) pnf=pnf->next[i];
    38             }
    39         }
    40     }
    41     for (int i=r;i>=1;i--) Q[i]->fail->cnt+=Q[i]->cnt;
    42 }
    43 
    44 int main(){
    45     scanf("%d",&n);
    46     root=new1(-1);
    47     for (int i=1;i<=n;i++){
    48         scanf("%s",s);
    49         wh[i]=root;
    50         int l=strlen(s);
    51         for (int j=0;j<l;j++) wh[i]=insert(wh[i],s[j]-'a'); 
    52     }
    53     build_fail();
    54     for (int i=1;i<=n;i++) printf("%d
    ",wh[i]->cnt);
    55     return 0;
    56 }
    View Code

    一开始zz把strlen放到循环里慢了十几倍

  • 相关阅读:
    VirtualBox4.3.12 安装ubuntu 14.04 分辨率过小(600*480)问题的解决方法
    asp.net 权限管理系统
    rdlc 格式设置
    Could not load file or assembly 'Microsoft.ReportViewer.Common, Version=11.0.0.0 异常处理
    Asp.Net Web Forms/MVC/Console App中使用Autofac
    Mysql优化小记1
    Zyan 一个通信框架
    RDLC
    通过.NET客户端异步调用Web API(C#)
    ECharts问题--散点图中对散点添加点击事件
  • 原文地址:https://www.cnblogs.com/karl07/p/6641812.html
Copyright © 2011-2022 走看看