zoukankan      html  css  js  c++  java
  • [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);
        }
    }
    正常的写法
  • 相关阅读:
    分布式01-Dubbo基础背景
    项目总结17-使用layui table分页表格
    项目总结16-创建验证码图片
    Springboot学习07-数据源Druid
    Springboot学习06-Spring AOP封装接口自定义校验
    Springboot学习05-自定义错误页面完整分析
    Springboot学习04-默认错误页面加载机制源码分析
    Springboot学习03-SpringMVC自动配置
    项目总结15:JavaScript模拟表单提交(实现window.location.href-POST提交数据效果)
    Springboot学习02-webjars和静态资源映射规则
  • 原文地址:https://www.cnblogs.com/zzzyc/p/8830262.html
Copyright © 2011-2022 走看看