【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
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞