zoukankan      html  css  js  c++  java
  • # 前缀统计~[字典树]

    前缀统计~[字典树]

    传送门

    题意

    给出N个字符串,进行M次询问,每次给出一个字符串,询问N个字符串中有多少个是它的前缀。

    思路

    字典树Trie入门题。

    字典树最典型的应用就是用来存储字符串。

    其中每个节点下有26个子节点(对应26个字母),根据新建节点的顺序使用idx为节点编号,根节点和空节点编号都为0,每个叶节点维护一个cnt,标记以这个叶节点结尾的字符串有几个。

    使用这种存储方式可以很容易查找一个字符串是否存在,以及出现过几次等等。

    Code:

    #include <bits/stdc++.h>
    using namespace std;
    #define fre freopen("data.in","r",stdin);
    #define ms(a) memset((a),0,sizeof(a))
    #define go(i,a,b) for(register int (i)=(a);(i)<(b);++(i))
    #define rep(i,a,b) for(register int (i)=(a);(i)<=(b);++(i))
    #define sf(x) scanf("%d",&(x))
    #define reg register
    typedef long long LL;
    const int inf=(0x3f3f3f3f);
    const int maxn=1e6+5;
    int son[maxn][30]; //维护字典树
    int cnt[maxn],idx,n,m; //idx为使用到的节点编号
    char str[maxn];
    inline void insert(char *str){
        int p=0,u;//p表示当前的根节点
        for(int i=0;str[i];++i){
            u=str[i]-'a';
            if(!son[p][u])son[p][u]=++idx; //如果这个节点不存在,那么为这个节点编号,表示新建这个节点,节点从1开始编号
            p=son[p][u]; //沿着节点一直走到叶节点
        }
        ++cnt[p];//统计以该叶节点结尾的字符串的个数
    }
    inline LL query(char *str){
        int p=0,u;
        LL ans=0;
        for(int i=0;str[i];++i){
            u=str[i]-'a';
            if(!son[p][u])return ans;
            ans+=cnt[son[p][u]];//遍历字符串,统计前缀
            p=son[p][u];
        }
        return ans;
    }
    int main(){
        sf(n);sf(m);
        while(n--){
            scanf(" %s",str);
            insert(str);
        }
        while(m--){
            scanf(" %s",str);
            printf("%lld
    ",query(str));
        }
        return 0;
    }
    
  • 相关阅读:
    如何在XSLT中实现勾选的效果
    6个jQuery图表Web应用扩展
    数据仓库(集市)之间共享维度表
    Json.NET
    jquery调用页面的方法
    使用javascript打开模态对话框
    使用ApplicationDeployment 类以编程方面对ClickOnce程序进行更新 【转载】
    XSLT 编译器 (xsltc.exe)
    在xslt中添加链接的方式
    哀悼
  • 原文地址:https://www.cnblogs.com/sstealer/p/12233104.html
Copyright © 2011-2022 走看看