【USACO08DEC】秘密消息Secret Message(二进制Trie树)

Trie树模板题,唯一的不同在与统计答案,设val[i]表示Trie树上经过i节点的单词数,end[i]表示在i节点结束的单词数。统计时,每走到一个节点就加上end[i];如果Trie树先走到尽头就直接返回答案;如果输入的先走完,那么最后一个节点不加end[i]而是val[i]。

特别注意:Trie树先走到尽头时一定要把剩下的输入读完再退出。

#include<cstdio>
using namespace std;
const int MAXN=500005;
int ch[MAXN*2][2],val[MAXN*2],end[MAXN*2],rt=0,np=0;

char c;
void scan(int &x)
{
	for(c=getchar();c<'0'||c>'9';c=getchar());
	for(x=0;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
}

char num[20];int ct;
void print(int x)
{
	ct=0;
	if(!x) num[ct++]='0';
	while(x) num[ct++]=x%10+'0',x/=10;
	while(ct--) putchar(num[ct]);
	putchar('\n');
}

int X;
void insert(int &now,int i)
{
	if(!now) now=++np;
	val[now]++;
	if(!i) 
	{
		end[now]++;
		return;
	}
	scan(X);i--;
	insert(ch[now][X],i);
}

int query(int now,int i)
{
	int ans=0;
	while(i--)
	{
		scan(X);
		now=ch[now][X];
		if(!now) //trie树走完了 
		{
			while(i--) scan(X); //记得全部读完 
			return ans;
		}
		if(!i) return ans+val[now];  //输入先走完,不加end而是val 
		ans+=end[now];
	}
	return ans;
}

int main()
{
	int N,M,x;
	scan(N);scan(M);
	for(int i=1;i<=N;i++)
	{
		scan(x);
		insert(rt,x);
	}
	while(M--)
	{
		scan(x);
		print(query(rt,x));
	}
	return 0;
}

 

    原文作者:Trie树
    原文地址: https://blog.csdn.net/WWWengine/article/details/82387405
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞