• [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
    ",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
    ",ans);
        }
    }
    正常的写法
  • 相关阅读:
    Docker常用命令总结(不断更新)
    Docker容器简介-与虚拟机的区别及安装步骤
    ELK搭建—安装使用Kibana可视化
    使用CURL与ElasticSearch服务进行通信
    安装部署ElasticSearch单节点在Linux服务器上
    ElasticStack分布式引擎技术栈(ELK)介绍
    为Nginx服务器配置黑(白)名单的防火墙
    php大力力 [026节] php开发状态要随时做好整理工作
    php大力力 [025节] 来不及学习和分类的,大力力认为有价值的一些技术文章合集(大力力二叔公)(2015-08-27)
    php大力力 [024节]PHP中的字符串连接操作(2015-08-27)
  • 原文地址:https://www.cnblogs.com/zzzyc/p/8830262.html
Copyright © 2020-2023  润新知