【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;
}



posted @ 2016-11-26 14:52  seasonal  阅读(72)  评论(0编辑  收藏  举报