【前缀个数】 前缀统计

传送门

题意

给定\(N\)个字符串,\(S_{1}、S_{2}、\dots S_{N}\)\(M\)个询问,每次询问给定一个字符串\(T\),求出在\(S_{1}、S_{2}、\dots S_{N}\)中有多少是\(T\)的子串

数据范围

字符串你的总长度\(\leq 10^{6}\)

题解

先将所有的字符串插入字典树之中,然后对每次给定的字符串\(T\),进行查询操作,累计以其中每个字符结尾的字符串个数即可、

  • 注意第一个节点也就是根是空节点

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)

const int N=1e5+10;

int trie[N][26],cnt[N],tot=1;
char s[N];
void insert(char s[])
{
    int p=1;
    for(int i=0;s[i];i++)
    {
        int c=s[i]-'a';
        if(!trie[p][c]) trie[p][c]=++tot;
        p=trie[p][c];
    }
    cnt[p]++;
}
int query(char s[])
{
    int res=0,p=1;
    for(int i=0;s[i];i++)
    {
        int c=s[i]-'a';
        if(!trie[p][c]) return res;
        p=trie[p][c]; 
        res+=cnt[p];
    }
    return res;
}
void solve()
{
    int n,m;
    cin>>n>>m;
    while(n--)
    {
        cin>>s;
        insert(s);
    }
    while(m--)
    {
        cin>>s;
        cout<<query(s)<<endl;   
    }
}

int main()
{
    solve();
    return 0;
}
posted @ 2020-07-27 17:50  Hyx'  阅读(190)  评论(0编辑  收藏  举报