zzzyc

导航

[HNOI2004]L语言

emm。。。这东西的名字好像好多啊。。。而且有多重搞法。。。

但是比较正常的写法空间复杂度要小于其他的,时间都差不多。。。

首先,什么事前缀树

一种多路树形结构,常用来操作字符串(但不限于字符串)

性质:不同字符串的相同前缀只保留一份。。。

操作:插入、查找、删除。。。

举个 栗子

假使我们有这样一些单词需要存入

那么最后会存成这个子:

 

 注意:根节点应该是个空节点。。。

意会一下之后就可以来看一道简单的模板题了

对于这道题我们可以发现这是。。。基本操作。。。

所以这里就不在赘述了。。。直接上代码好了。。。

至于如何存储和查找看看代码应该也就理解了。。。

呆码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define jj k+ch[i]-'a'
using namespace std;
char ch[1000010];
int hash=26,l,n,m,w[30000010];
bool v[30000010],use[3000010];

inline void putin()
{
    int k=0;
    for(int i=0;i<=l-1;i++)
    {
        if(!w[jj]) w[jj]=hash,hash+=26;
        k=w[jj];
        if(i==l-1) v[k]=1;
    }
}

inline void find(int x)
{
    int k=0;
    for(int i=x;i<=l-1;i++)
    {
        if(!w[jj]) return;
        k=w[jj];
        if(v[k]) use[i]=1;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch);
        l=strlen(ch);
        putin();
    }

    for(int i=1;i<=m;i++)
    {
        int ans=0;
        memset(use,0,sizeof(use));
        scanf("%s",ch);
        l=strlen(ch);
        find(ans);
        for(int j=0;j<=l-1;j++)
            if(use[j])
            {
                ans=j+1;
                find(ans);
            }
        printf("%d\n",ans);
    }
}
自己手胡的辣鸡做法

呆码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 20*10+10
#define MAXN 1024*1024+10
using namespace std;
char ch[MAXN];
int n,m,rt=1,cnt=1,trie[maxn][26];
bool use[MAXN],mark[maxn];

inline void insert(int &x,int now,int l)
{
    if(!x) x=++cnt;
    if(now==l) mark[x]=1;
    else insert(trie[x][ch[now]-'a'],now+1,l);
}

inline void find(int x,int now,int l)
{
    if(mark[x] && x) use[now]=1;
    if(!x || now==l) return;
    find(trie[x][ch[now]-'a'],now+1,l);
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch); int l=strlen(ch);
        insert(rt,0,l);
    }

    for(int i=1;i<=m;i++)
    {
        scanf("%s",ch); int l=strlen(ch);
        int ans=0;
        memset(use,0,sizeof(use));
        use[0]=1;
        for(int j=0;j<=l;j++)
            if(use[j])
            {
                find(rt,j,l);
                ans=j;
            }
        printf("%d\n",ans);
    }
}
正常的写法

 

posted on 2018-04-14 09:19  zzzyc  阅读(178)  评论(0编辑  收藏  举报