码迷,mamicode.com
首页 > Windows程序 > 详细

AcWing 142. 前缀统计 字典树打卡

时间:2019-05-20 21:03:16      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:\n   pre   cout   节点   i++   return   code   long   clu   

给定N个字符串S1,S2SNS1,S2…SN,接下来进行M次询问,每次询问给定一个字符串T,求S1S1~SNSN中有多少个字符串是T的前缀。

输入字符串的总长度不超过106106,仅包含小写字母。

输入格式

第一行输入两个整数N,M。

接下来N行每行输入一个字符串SiSi。

接下来M行每行一个字符串T用以询问。

输出格式

对于每个询问,输出一个整数表示答案。

每个答案占一行。

输入样例:

3 2
ab
bc
abc
abc
efg

输出样例:

2
0


题意:让你计算前面有多少个字符串是查询的这个字符串的前缀
思路:这是字符串的题,在字符串算法中和前缀有关的是字典树,模板中是计算这个串是多少个串的前缀,其实这题大同小异,我们在前面插入的时候最后那个节点才加一,然后查询时
直接加上沿途所有的值
#include<bits/stdc++.h>
#define maxn 1000005
#define mod 1000000007
using namespace std;
typedef long long ll;
ll n,m;
char str[maxn];
ll tree[maxn][26];
ll sum[maxn];
ll top;
void insert(){
    int len=strlen(str);
    ll root=0;
    for(int i=0;i<len;i++){
        ll x=str[i]-a;
        if(!tree[root][x]) tree[root][x]=++top;
        root=tree[root][x];
     }
     sum[root]++;//因为是要计算有多少个字符串是查询的前缀就只能当前节点加一了
}
ll query(){
    ll num=0;
    ll root=0;
    for(int i=0;str[i]!=\0;i++){
        ll x=str[i]-a;
        if(!tree[root][x]) return num;
        root=tree[root][x];
        num+=sum[root];//加上以当前节点结尾的字符串个数
    }
    return num;
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%s",str);
        insert();
    }
    for(int j=0;j<m;j++){
        scanf("%s",str);
        cout<<query()<<"\n"; 
    }
} 

 

 

AcWing 142. 前缀统计 字典树打卡

标签:\n   pre   cout   节点   i++   return   code   long   clu   

原文地址:https://www.cnblogs.com/Lis-/p/10896359.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!