题意:

     给你一个字典,最多4000个单词,每个单词长度最多是100,然后给你一个串,问你这个子串可以被那些单词组合的组合数,比如字典里有4个单词a b ab cd,然后给你一个串abcd则abcd = a+b+cd,ab+cd一共两种组合。输出组合数对20071027取余(白书上写错了写的是20071207)

思路:

       我们可以找到一个递推公式,d[i] = sum(i + len[x]),解释一下这个,d[i]表示的是以i个位置为开头的字符串的组合个数,就是[i,i+1,i+2..len-1],而x则是以i开头的那个串的前缀,这样就不难理解了吧,整体意思就是如果defg = 5,那么只要存在bc,就可以得到以a开头的abcdefg可以加上5了,然后就是优化时间,因为直接暴力写的话30000*4000*判断前缀匹配,时间复杂度接受不了,既然是前缀,我们可以想到字典树,我们可以把所有的4000个单词都放到字典里,然后在匹配的时候如果碰到单词末尾节点,直接就是找到满足条件,更新左右值,就行了,具体看代码,很容易理解。

PS不要把30000的那个字符串拆开放到字典树里,一开始我就是这么想的,结果还没敲完意识到这样内存会很大,很可能会爆内存,还有就是别忽视strlen这个函数的时间复杂度,TLE了一次。

      

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#define N 300000 + 10

#define MOD 20071027

typedef struct Tree

{

    Tree *next[26];

    int mk;

}Tree;

Tree root;

char Str[N];

long long dp[N];

void BuidTree(char *str)

{

    int len = strlen(str);

    Tree *p = &root ,*q;

    for(int i = 0 ;i < len ;i ++)

    {

        int id = str[i] - 'a';

        if(p -> next[id] == NULL)

        {

            q = (Tree *)malloc(sizeof(root));

            q -> mk = 0;

            for(int j = 0 ;j < 26 ;j ++)

            q -> next[j] = NULL;

            p -> next[id] = q;

            p = p -> next[id];

        }

        else

        p = p -> next[id];

    }

    p -> mk = 1;

}

void Query(char *str ,int ii ,int len)

{

    dp[ii] = 0;

    Tree *p = &root;

    for(int i = ii ;i < len ;i ++)

    {

        int id = str[i] - 'a';

        p = p -> next[id];

        if(p == NULL) break;

        if(p -> mk) dp[ii] = (dp[ii] + dp[i+1]) % MOD;

    }

    return ;

}

int main ()

{

    int cas = 1 ,i ,n;

    char tmp[105];

    while(~scanf("%s" ,Str))

    {

        scanf("%d" ,&n);

        for(i = 0 ;i < 26 ;i ++)

        root.next[i] = NULL;

        for(i = 1 ;i <= n ;i ++)

        {

            scanf("%s" ,tmp);

            BuidTree(tmp);

        }

        int len = strlen(Str);

        dp[len] = 1;

        for(i = len - 1 ;i >= 0 ;i --)

        {

            Query(Str ,i ,len);//把len直接传下去,别在里面从求,会超时。

        }

        printf("Case %d: %lld\n" ,cas ++ ,dp[0]);

    }

}

LA3942字典树+递推的更多相关文章

  1. [BZOJ1089][SCOI2003]严格n元树(递推+高精度)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最 ...

  2. bzoj 1089 SCOI2003严格n元树 递推

    挺好想的,就是一直没调过,我也不知道哪儿的错,对拍也拍了,因为数据范围小,都快手动对拍了也不知道 哪儿错了.... 我们定义w[i]代表深度<=i的严格n元树的个数 那么最后w[d]-w[d-1 ...

  3. Codeforces 446C 线段树 递推Fibonacci公式

    聪哥推荐的题目 区间修改和区间查询,但是此题新颖之处就在于他的区间修改不是个定值,而是从L 到 R 分别加 F1.F2....Fr-l+1 (F为斐波那契数列) 想了一下之后,觉得用fib的前缀和来解 ...

  4. BZOJ 1089 严格n元树 (递推+高精度)

    题解:用a[i]表<=i时有几种树满足度数要求,那么这样就可以递归了,a[i]=a[i-1]^n+1.n个节点每个有a[i-1]种情况,那么将其相乘,最后加上1,因为深度为0也算一种.那么答案就 ...

  5. 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】

    还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...

  6. 【BZOJ】1089: [SCOI2003]严格n元树(递推+高精度/fft)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1089 题意:求深度为d的n元树数目.(0<n<=32, 0<=d<=16) ...

  7. HDU 4747 Mex 递推/线段树

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=4747 Mex Time Limit: 15000/5000 MS (Java/Others)Memory Limi ...

  8. 【主席树维护mex】 【SG函数递推】 Problem H. Cups and Beans 2017.8.11

    Problem H. Cups and Beans 2017.8.11 原题: There are N cups numbered 0 through N − 1. For each i(1 ≤ i ...

  9. ACM学习历程—UESTC 1217 The Battle of Chibi(递推 && 树状数组)(2015CCPC C)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1217 题目大意就是求一个序列里面长度为m的递增子序列的个数. 首先可以列出一个递推式p(len, i) =  ...

随机推荐

  1. Linux安全模型中的3A

    3A Authentication : 认证 验证用户身份 Authorization : 授权 不同用户设置不同权限 Accouting | Audition : 审计 Linux 验证用户身份 U ...

  2. 关于win10 编辑文件时权限不足问题

    win10默认是不开启administrator账户的,所以一般是自己创建一个账户,但是此账户,可能会有些文件或文件夹,访问不了,编辑不了,这时候,只需要右键->属性->安全->编辑 ...

  3. go中sync.Once源码解读

    sync.Once 前言 sync.Once的作用 实现原理 总结 sync.Once 前言 本次的代码是基于go version go1.13.15 darwin/amd64 sync.Once的作 ...

  4. 推荐!!! Markdown图标索引网站

    作者:三十三重天 博客: http://www.zhouhuibo.club 我们在观察别人的文章时候时,总能看到很多有趣的图标,像是这样

  5. Memory Networks01 记忆网络经典论文

    目录 1.Memory Networks 框架 流程 损失函数 QA 问题 一些扩展 小结 2.End-To-End Memory Networks Single Layer 输入模块 算法流程 Mu ...

  6. 【odoo14】第六章、管理模块数据

    本章代码可在原作者github下载 使用外部ID及命名空间 外部ID及XML ID用于标记记录.到目前为止,我们在视图.菜单及动作中接触了XML IDs.本节我们将进一步了解什么是XML ID. 步骤 ...

  7. Git - 使用命令和P4Merge进行diff

    P4Merge P4Merge是Git的一个第三发Diff和Merge工具(可视化冲突解决工具). 下载地址: https://www.perforce.com/downloads/visual-me ...

  8. Java学习之路 -- Java怎么学?

    @ 目录 java基础怎么学? 学完基础学什么? 几个常用框架学完学什么? MQ JVM的知识跑不掉 微服务等等 其他 数据结构和算法 java基础怎么学? 当时,作为懵懂的小白,大一学习了c和c++ ...

  9. Python基础之数据类型详解

    为什么会有数据类型? 在介绍具体的数据类型之前,需要了解为什么需要区分数据类型.我们知道,一个公司会有很多个大的部门,每个部门下又会有许多细分的小部门,构成了公司的完整体系结构.如果把python的数 ...

  10. 为科学计算而生的Julia——基于Manjaro Linux的安装与入门

    技术背景 Julia是一门为科学计算而生的编程语言,其着重强调了开源.生态与性能.从开源角度来说,相比于Matlab就要友好很多,用户可以免费使用,而且MIT协议应该是最宽松的开源协议之一(截图来自于 ...