BZOJ 1590.Secret Message 秘密信息(Trie树) [Usaco2008 Dec]BZOJ计划
Posted 繁凡さん
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1590.Secret Message 秘密信息(Trie树) [Usaco2008 Dec]BZOJ计划相关的知识,希望对你有一定的参考价值。
整理的算法模板合集: ACM模板
实际上是一个全新的精炼模板整合计划
BZOJ简单题合集x
Weblink
https://hydro.ac/d/bzoj/p/1590
Problem
Solution
字符串前缀完全匹配,显然考虑 Trie 树,首先建立 Trie 树,根节点 p = 1 p=1 p=1 不包含任何字符,新节点从 2 2 2 开始。
分析题意,由于匹配串与模式串只要有一个串结束均算作一种匹配,所以显然分为两种情况:
- 模式串结束
显然在 Trie 树中移动的过程中,把经过的所有的以当前字符结尾的字符串数量全部加上,设ed[x]
以当前节点 x x x 为结束点的字符串个数,我们在移动的过程中累加路径上所有的ed
值即可。 - 匹配串结束
显然匹配串结束了,那么经过这个字符的所有模式串全都匹配成功,所以应该加上所有经过这个字符的模式串的个数,设sum[x]
表示经过节点 x x x 的字符串个数加起来即可。注意由于我们在移动的时候把所有的ed
全部都加上去了,多加了一个ed
,所以这里需要在减去ed[x]
。
Code
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
const int maxn = 5e4 + 7, maxs = 5e5 + 7;
int n, m, t, k;
ll ans;
int s[maxs];
int tot;
int trie[maxs][3];
int sum[maxs];
int ed[maxs];
void insert(int x[], int len)
int p = 1;
for (int i = 1; i <= len; ++ i)
int ch = x[i];
if (trie[p][ch] == -1)
trie[p][ch] = ++ tot;
p = trie[p][ch];
sum[p] ++ ;
ed[p] ++ ;
ll search(int x[], int len)
int p = 1;
ll res = 0;
for (int i = 1; i <= len; ++ i)
int ch = x[i];
if(trie[p][ch] == -1)
return res;
p = trie[p][ch];
res += ed[p];
return res + sum[p] - ed[p];
int main()
tot = 1;
memset(trie, -1, sizeof trie);
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++ i)
int len;
scanf("%d", &len);
for (int j = 1; j <= len; ++ j)
scanf("%d", &s[j]);
insert(s, len);
for (int i = 1; i <= m; ++ i)
int len;
scanf("%d", &len);
for (int j = 1; j <= len; ++ j)
scanf("%d", &s[j]);
printf("%lld\\n", search(s, len));
return 0;
以上是关于BZOJ 1590.Secret Message 秘密信息(Trie树) [Usaco2008 Dec]BZOJ计划的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1590: [Usaco2008 Dec]Secret Message 秘密信息
[BZOJ1590] [Usaco2008 Dec]Secret Message 秘密信息(字典树)
BZOJ1590: [Usaco2008 Dec]Secret Message 秘密信息
BZOJ1590: [Usaco2008 Dec]Secret Message 秘密信息
bzoj1590Usaco2008 Dec秘密消息Secret Message
在 Python 中如何将 `email.message.Message` 对象转换为 `email.message.EmailMessage` 对象