【Trie的模板】例题11 LA3942 Remember the Word(字典树+dp)
Trie也就是字典树,可以处理一些字符串的查找问题,写起来还是很简单的,下面记录一下模板:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxnode = 400000;
const int sigma_size = 28;
struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz; //节点总数
int idx(char c) { return c - 'a'; }
void build()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
void insert(string s, int v)//v是插入单词的长度
{
int u = 0, n = s.length();
for (int i = 0; i < n; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;//指向下一个节点
}
u = ch[u][c];
}
val[u] = v;//这个节点不为0说明是一个完整单词
}
bool query(string s)
{
int u = 0, n = s.length(), ans = 0;
for (int i = 0; i < n; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
cout << "字符串不在树中" << endl;
return false;
}
u = ch[u][c];
}
if (val[u])
{
cout << "字符串在树中" << endl;
return true;
}
else
{
cout << "字符串不在树中但是前缀" << endl;
return 0;
}
}
}tree;
下面是道例题:
例题11 LA3942 Remember the Word:
具体题意和实现看白书
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxnode = 400000;
const int sigma_size = 28;
const int mod = 20071027;
int dp[300005];
int num;
string deal;
struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz; //节点总数
int idx(char c) { return c - 'a'; }
void build()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
void insert(string s, int v)//v是每个节点的权值,为0说明这个节点不是单词节点
{
int u = 0, n = s.length();
for (int i = 0; i < n; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;//指向下一个节点
}
u = ch[u][c];
}
val[u] = v;
}
int query(string s, int now)
{
int u = 0, n = s.length(), ans = 0;
for (int i = 0; i < n; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
return ans;
u = ch[u][c];
if (val[u])
ans = (ans + dp[now + val[u]]) % mod;
}
return ans;
}
}tree;
int main()
{
int n;
while (cin >> deal)
{
tree.build();
string str;
int len = deal.length();;
int MAX = 0;
cin >> n;
while (n--)
{
cin >> str;
int len1 = str.length();
tree.insert(str, len1);
MAX = max(MAX, len1);
}
memset(dp, 0, sizeof(dp));
dp[len] = 1;
for (int i = len - 1; i >= 0; i--)
{
dp[i] = (dp[i] + tree.query(deal.substr(i, min(len - i, MAX)), i))%mod;
}
cout << "Case " << ++num << ": " << dp[0] << endl;
}
return 0;
}