1 条题解

  • 0
    @ 2025-8-24 22:37:52

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar qip101
    哪怕是一只萤火虫喜欢上月亮,它也会想把自己所有的光都给它。跟喜欢的人多强大没关系,这是跳动不止的心意。

    搬运于2025-08-24 22:37:52,当前版本为作者最后更新于2022-05-17 10:24:28,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    一.什么是字典树

    Trie 树,即字典树,是一种树形结构。典型应用是用于统计和排序大量的字符串前缀来减少查询时间,最大限度地减少无谓的字符串比较。

    Trie 树的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

    二.字典树的性质

    1.根节点不包含字符,除根节点外每一个节点都只包含一个字符。

    2.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

    3.每个节点的所有子节点包含的字符都不相同。

    下图就是一个字典树:

    三.字典树的操作

    1.映射字符

    int getnum(char x){
        if(x>='A'&&x<='Z')
            return x-'A';
        else if(x>='a'&&x<='z')
            return x-'a'+26;
        else
            return x-'0'+52;
    } 
    

    2.插入字符串

    void insert(char str[])
    {
        int p=0,len=strlen(str);
        for(int i=0;i<len;i++)
        {
            int c=getnum(str[i]);
            if(!t[p][c])
                t[p][c]=++idx;
            p=t[p][c];
            cnt[p]++;
        }
    }
    

    3.查询操作

    int find(char str[])
    {
        int p=0,len=strlen(str);
        for(int i=0;i<len;i++)
        {
            int c=getnum(str[i]);
            if(!t[p][c])
                return 0;
            p=t[p][c];
        }
        return cnt[p];
    }
    

    4.main 函数部分

    int main(){
        scanf("%d",&T);
        while(T--)
        {
            for(int i=0;i<=idx;i++)
                for(int j=0;j<=122;j++)
                    t[i][j]=0;
            for(int i=0;i<=idx;i++)
                cnt[i]=0;
            idx=0;
            scanf("%d%d",&n,&q);
            for(int i=1;i<=n;i++)
            {
                scanf("%s",s);
                insert(s);
            }
            for(int i=1;i<=q;i++)
            {
                scanf("%s",s);
                printf("%d\n",find(s));
            }
        }
        return 0;
    }
    

    四.代码

    #include<bits/stdc++.h>
    using namespace std;
    int T,q,n,t[3000005][65],cnt[3000005],idx;
    char s[3000005];
    int getnum(char x){
        if(x>='A'&&x<='Z')
            return x-'A';
        else if(x>='a'&&x<='z')
            return x-'a'+26;
        else
            return x-'0'+52;
    } 
    void insert(char str[]){
        int p=0,len=strlen(str);
        for(int i=0;i<len;i++){
            int c=getnum(str[i]);
            if(!t[p][c])
                t[p][c]=++idx;
            p=t[p][c];
            cnt[p]++;
        }
    }
    int find(char str[]){
        int p=0,len=strlen(str);
        for(int i=0;i<len;i++){
            int c=getnum(str[i]);
            if(!t[p][c])
                return 0;
            p=t[p][c];
        }
        return cnt[p];
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            for(int i=0;i<=idx;i++)
                for(int j=0;j<=122;j++)
                    t[i][j]=0;
            for(int i=0;i<=idx;i++)
                cnt[i]=0;
            idx=0;
            scanf("%d%d",&n,&q);
            for(int i=1;i<=n;i++){
                scanf("%s",s);
                insert(s);
            }
            for(int i=1;i<=q;i++){
                scanf("%s",s);
                printf("%d\n",find(s));
            }
        }
        return 0;
    }
    
    • 1

    信息

    ID
    7466
    时间
    1000ms
    内存
    1024MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者