zoukankan      html  css  js  c++  java
  • bzoj 1212: [HNOI2004]L语言 AC自动机+状压

      为什么这道题网上所有题解写的都是N*Len的trie树的暴力啊,4E的复杂度。。。

      为什么暴力还跑这么快啊TAT。。

      有一个O(Len)的做法就是先把AC自动机建出来,因为每个字典串的长度很小,所以我们可以用fail树状压一发,每个节点记录一个值ss,表示这个点向前(1~10)的长度的串是不是一个字典串,这个东西延fail树递推就行了。

      然后每次把每个串放AC自动机上走,同时记录一个值T表示(s(1,i-11)~s(1-(i-1)))这些串能否成为答案,如果如果T&ss!=0那么i这个点就可以成为答案。

      

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 int n,m;
     8 char s[1500000];
     9 int ch[1005][26];int cnt;int v[10005];
    10 int fail[1005];int len[1005];
    11 void insert()
    12 {
    13     int ln=strlen(s);int now=0;
    14     for(int i=0;i<ln;i++)
    15     {
    16         int c=s[i]-'a';
    17         if(ch[now][c])
    18         {
    19             now=ch[now][c];
    20         }
    21         else
    22         {
    23             ch[now][c]=++cnt;
    24             len[cnt]=len[now]+1;
    25             now=ch[now][c];
    26         }
    27     }
    28     v[now]=1;
    29 }
    30 queue<int>q;
    31 unsigned int ss[1005];
    32 void build()
    33 {
    34     for(int i=0;i<26;i++)if(ch[0][i])q.push(ch[0][i]);
    35     while(!q.empty())
    36     {
    37         int tmp=q.front();q.pop();
    38         for(int i=0;i<26;i++)
    39         {
    40             if(ch[tmp][i])
    41             {
    42                  q.push(ch[tmp][i]);
    43                  fail[ch[tmp][i]]=ch[fail[tmp]][i];
    44             }
    45             else
    46             {
    47                 ch[tmp][i]=ch[fail[tmp]][i];
    48             }
    49         }
    50         if(v[tmp])ss[tmp]=(ss[fail[tmp]]^(1<<(len[tmp]-1)));
    51         else ss[tmp]=ss[fail[tmp]];
    52     }
    53     return ;
    54 }
    55 unsigned int tmp;
    56 void solve()
    57 {
    58     int ans=0;
    59     unsigned int ssr=1;
    60     int ln=strlen(s+1);
    61     int now=0;
    62     for(int i=1;i<=ln;i++)
    63     {
    64         int c=s[i]-'a';
    65         now=ch[now][c];
    66         tmp=ssr;
    67         ssr<<=1;
    68         if(tmp&ss[now])ans=max(ans,i),ssr^=1;
    69     }
    70     printf("%d
    ",ans);
    71     return ;
    72 }
    73 int main()
    74 {
    75     scanf("%d%d",&n,&m);
    76     for(int i=1;i<=n;i++)
    77     {
    78         scanf("%s",s);
    79         insert();
    80     }
    81     build();
    82     for(int i=1;i<=m;i++)
    83     {
    84         scanf("%s",s+1);
    85         solve();
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    zookeeper使用场景
    zookeeper安装配置
    hadoop 远程调试
    deep learning笔记
    Sentiment Analysis(1)-Dependency Tree-based Sentiment Classification using CRFs with Hidden Variables
    PRML阅读笔记 introduction
    Python 学习笔记(2)
    python nltk 学习笔记(5) Learning to Classify Text
    python nltk 学习笔记(4) Writing Structured Programs
    python nltk 学习笔记(3) processing raw text
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6479656.html
Copyright © 2011-2022 走看看