bzoj 1212 [HNOI2004] L语言(不用AC自动机)

网上的题解大多树都要建一棵trie树,并在上面跑AC自动机,然而这里有一种同样需要trie树,但时间复杂度较低的方法。

首先,我们可以轻松列出状态转移方程 F[x]=∑| F[x-len(i)]&(is(i->x,s[i]);

这样的复杂度是O(m*lens*∑len[i]*n),可能会超时,再加上hash之类的就可以过了,但这显然不优美。

====================分割线====================

对于每个F(i),我们都是从之前的额某个F(j)转移过来的,它是true当且仅当(j+1->i)是一个单词,且f[j]是true,那么我们将每个单词反过来建一棵trie树,例如有单词abc,我们将cba插入trie树,从i开始i先匹配到每个单词的最后一位,然后再匹配到最后一位相同的倒数第二位,如此下去,当我们匹配到一个单词的开头时,并且此时的F[i-depth]为true的话,F(i)就为true了,因为每个字符在trie树上的路径唯一,且trie树的深度不超过单词的最长长度(10),所以它的复杂度还是非常可看的,复杂度为O(m*lens*dep(trie))=O(m*lens*max(strlen(word))),20*1M*10,轻松过。

这题不难,但是如果反过来想,可以避免很多高端算法,从后往前的思想确实不错。贴一个代码,有些冗长。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 using namespace std;
 6 int ch[10005][20];
 7 int cnt;
 8 int n,m;
 9 char s[2000005];
10 int col[2000005];
11 bool dp[1000005];
12 void insert()
13 {
14     int now=0;
15     for(int i=strlen(s)-1;i>=0;i--)
16     {
17         int c=s[i]-'0';
18         if(!ch[now][c])
19         {
20             cnt++;
21             ch[now][c]=cnt;
22         }
23         now=ch[now][c];
24     }
25     col[now]=true;
26 }
27 bool cal(int x)
28 {
29     int deep=0;
30     int now=0;
31     for(int i=x;i>=1;i--)
32     {
33         int c=s[i]-'0';
34         if(ch[now][c]==0)return false;
35         now=ch[now][c];
36         deep++;
37         if(dp[x-deep] && col[now])return true;
38     }
39     return true;
40 }
41 void solve()
42 {
43     int ll=strlen(s+1);
44     for(int i=1;i<=ll;i++)
45     {
46         dp[i]=cal(i);
47     }
48     for(int i=ll;i>=0;i--)
49     {
50         if(dp[i])
51         {
52             printf("%d\n",i);
53             return;
54         }
55     }
56     return ;
57 }
58 int main()
59 {
60     scanf("%d%d",&n,&m);
61     for(int i=1;i<=n;i++)
62     {
63         scanf("%s",s);
64         insert();
65     }
66     for(int i=1;i<=m;i++)
67     {
68         memset(dp,0,sizeof(dp));
69         dp[0]=true;
70         scanf("%s",s+1);
71         solve();
72     }
73     return 0;
74 }
View Code

 

posted @ 2015-07-12 16:01  溪桥,吾愿  阅读(253)  评论(0编辑  收藏  举报