HDU 2846 Repository(字典树,标记)

题目

字典树,注意初始化的位置~!!位置放错,永远也到不了终点了org。。。。

我是用数组模拟的字典树,这就要注意内存开多少了,,要开的不大不小刚刚好真的不容易啊。。。。

我用了val来标记是否是同一个串分解而来的,保存的是串的编号

num记录数目。

//string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);
//把[first0,last0)之间的部分替换成[first,last)之间的字符串


#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
using namespace std;
#define ll __int64
int pos;
struct tt
{
    int val,arr[27],num;
    tt(){
        val=-1,num=0;
        memset(arr,-1,sizeof(arr));
    }
}a[500010]; //用数组模拟的字典树开的内存大小也是一个技术活,太大超内存,太小runtime errer。。

void insert(char *s,int val,int id,int d)
{
    if(s[d]=='')return;

    int t=s[d]-'a';
    if(a[id].arr[t]==-1)
        a[id].arr[t]=++pos;
    id=a[id].arr[t];
    if(a[id].val!=val)
    {
        a[id].val=val;
        a[id].num++;
    }
    insert(s,val,id,d+1);
}
int solve(char *s,int id)
{
    int ans=0;
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int t=s[i]-'a';
        if(a[id].arr[t]==-1)
            return 0;
        else 
            id=a[id].arr[t];
    }
    return a[id].num;
}

int main()
{
    int t;
    pos=0;//注意初始化的位置
    scanf("%d",&t);
    while(t--)
    {
        char s[30];
        scanf("%s",s);
        int len=strlen(s);
        for(int i=0;i<len;i++)
        {
            insert(s+i,t,0,0);
        }
    }
    int n;
    scanf("%d",&n);
    while(n--)
    {
        char s[30];
        scanf("%s",s);
        int ans=solve(s,0);
        printf("%d
",ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/laiba2004/p/3909503.html