BZOJ1590: [Usaco2008 Dec]Secret Message 秘密信息
Posted Blue233333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1590: [Usaco2008 Dec]Secret Message 秘密信息相关的知识,希望对你有一定的参考价值。
给n<=50000条01串,m<=50000个询问,每次给出一个01串求有多少个n条中有多少是它的前缀以及它是多少条的前缀。
前缀?Trie!匹配时记一路上单词节点的总量加上最后一个节点子树中单词节点总量即可。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 //#include<iostream> 6 using namespace std; 7 8 int n,m; 9 #define maxn 500011 10 bool a[maxn];int len; 11 struct Trie 12 { 13 int ch[maxn][2],size; 14 int val[maxn],tot[maxn]; 15 Trie() {size=0;ch[0][0]=ch[0][1]=0;} 16 void insert() 17 { 18 int now=0; 19 for (int i=1;i<=len;i++) 20 { 21 if (!ch[now][a[i]]) 22 { 23 size++; 24 val[size]=0; 25 tot[size]=0; 26 ch[now][a[i]]=size; 27 ch[size][0]=ch[size][1]=0; 28 } 29 now=ch[now][a[i]]; 30 tot[now]++; 31 } 32 val[now]++; 33 } 34 int find() 35 { 36 int now=0,ans=0; 37 for (int i=1;i<=len;i++) 38 { 39 if (!ch[now][a[i]]) return ans; 40 now=ch[now][a[i]]; 41 ans+=val[now]; 42 } 43 return ans+tot[now]-val[now]; 44 } 45 }t; 46 int x; 47 int main() 48 { 49 scanf("%d%d",&n,&m); 50 for (int i=1;i<=n;i++) 51 { 52 scanf("%d",&len); 53 for (int j=1;j<=len;j++) scanf("%d",&x),a[j]=x; 54 t.insert(); 55 } 56 for (int i=1;i<=m;i++) 57 { 58 scanf("%d",&len); 59 for (int j=1;j<=len;j++) scanf("%d",&x),a[j]=x; 60 printf("%d\n",t.find()); 61 } 62 return 0; 63 }
以上是关于BZOJ1590: [Usaco2008 Dec]Secret Message 秘密信息的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1590.Secret Message 秘密信息(Trie树) [Usaco2008 Dec]BZOJ计划
[BZOJ1590] [Usaco2008 Dec]Secret Message 秘密信息(字典树)
BZOJ1590: [Usaco2008 Dec]Secret Message 秘密信息
BZOJ1590: [Usaco2008 Dec]Secret Message 秘密信息