hdu 2846 字典树变形

mark: 题目有字串匹配的过程 有两点

1.为了高效的匹配子串 可以把所有的子串都预处理进去 然后字典树计数就放在最后面

2.在同一个母串处理自串的时候 会有重复的时候 比如abab  这里去重用个标记位就可以了(一开始用map 结果超时了,,,  果然还是想太简单了)

上代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<string>
#define maxn 27
using namespace std;
struct Tri
{
    int num,id;
    Tri*next[maxn];
    Tri()
    {
        num=0,id=0;
        memset(next,0,sizeof(next));
    }
};
void buildTri(Tri*root,string str,int ret)
{
    for(int i=0;i<str.size();i++)
    {
        int id=str[i]-'a';
        if(root->next[id]==NULL) root->next[id]=new Tri();
        root=root->next[id];
    }
    if(root->id!=ret) root->num++,root->id=ret;//  序号不一样的时候 计数 然后标记更新
}
int findTri(Tri *root,string str)
{
    for(int i=0;i<str.size();i++)
    {
        int id=str[i]-'a';
        if(root->next[id]==NULL) return 0;
        root=root->next[id];
    }
    return root->num;
}
int main()
{
    cin.sync_with_stdio(false);
    int t;
    string ss;
    cin>>t;
    Tri *root=new Tri();//
    for(int ii=1;ii<=t;ii++)
    {
        cin>>ss;
        int len=ss.size();
        string zz;
        map<string,int> fuck;
        for(int i=0;i<ss.size();i++)// 预处理过程 将所有的字串都放进去
        {
            for(int j=1;j<=ss.size()-i;j++)
            {
                zz=ss.substr(i,j);
                buildTri(root,zz,ii);
            }
        }
    }
    cin>>t;
    while(t--)
    {
        cin>>ss;
        cout<<findTri(root,ss)<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/z1141000271/p/5978536.html