LA3942字典树+递推
题意:
给你一个字典,最多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字典树+递推的更多相关文章
- [BZOJ1089][SCOI2003]严格n元树(递推+高精度)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最 ...
- bzoj 1089 SCOI2003严格n元树 递推
挺好想的,就是一直没调过,我也不知道哪儿的错,对拍也拍了,因为数据范围小,都快手动对拍了也不知道 哪儿错了.... 我们定义w[i]代表深度<=i的严格n元树的个数 那么最后w[d]-w[d-1 ...
- Codeforces 446C 线段树 递推Fibonacci公式
聪哥推荐的题目 区间修改和区间查询,但是此题新颖之处就在于他的区间修改不是个定值,而是从L 到 R 分别加 F1.F2....Fr-l+1 (F为斐波那契数列) 想了一下之后,觉得用fib的前缀和来解 ...
- BZOJ 1089 严格n元树 (递推+高精度)
题解:用a[i]表<=i时有几种树满足度数要求,那么这样就可以递归了,a[i]=a[i-1]^n+1.n个节点每个有a[i-1]种情况,那么将其相乘,最后加上1,因为深度为0也算一种.那么答案就 ...
- 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】
还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...
- 【BZOJ】1089: [SCOI2003]严格n元树(递推+高精度/fft)
http://www.lydsy.com/JudgeOnline/problem.php?id=1089 题意:求深度为d的n元树数目.(0<n<=32, 0<=d<=16) ...
- HDU 4747 Mex 递推/线段树
题目链接: acm.hdu.edu.cn/showproblem.php?pid=4747 Mex Time Limit: 15000/5000 MS (Java/Others)Memory Limi ...
- 【主席树维护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 ...
- ACM学习历程—UESTC 1217 The Battle of Chibi(递推 && 树状数组)(2015CCPC C)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1217 题目大意就是求一个序列里面长度为m的递增子序列的个数. 首先可以列出一个递推式p(len, i) = ...
随机推荐
- Linux安全模型中的3A
3A Authentication : 认证 验证用户身份 Authorization : 授权 不同用户设置不同权限 Accouting | Audition : 审计 Linux 验证用户身份 U ...
- 关于win10 编辑文件时权限不足问题
win10默认是不开启administrator账户的,所以一般是自己创建一个账户,但是此账户,可能会有些文件或文件夹,访问不了,编辑不了,这时候,只需要右键->属性->安全->编辑 ...
- go中sync.Once源码解读
sync.Once 前言 sync.Once的作用 实现原理 总结 sync.Once 前言 本次的代码是基于go version go1.13.15 darwin/amd64 sync.Once的作 ...
- 推荐!!! Markdown图标索引网站
作者:三十三重天 博客: http://www.zhouhuibo.club 我们在观察别人的文章时候时,总能看到很多有趣的图标,像是这样
- Memory Networks01 记忆网络经典论文
目录 1.Memory Networks 框架 流程 损失函数 QA 问题 一些扩展 小结 2.End-To-End Memory Networks Single Layer 输入模块 算法流程 Mu ...
- 【odoo14】第六章、管理模块数据
本章代码可在原作者github下载 使用外部ID及命名空间 外部ID及XML ID用于标记记录.到目前为止,我们在视图.菜单及动作中接触了XML IDs.本节我们将进一步了解什么是XML ID. 步骤 ...
- Git - 使用命令和P4Merge进行diff
P4Merge P4Merge是Git的一个第三发Diff和Merge工具(可视化冲突解决工具). 下载地址: https://www.perforce.com/downloads/visual-me ...
- Java学习之路 -- Java怎么学?
@ 目录 java基础怎么学? 学完基础学什么? 几个常用框架学完学什么? MQ JVM的知识跑不掉 微服务等等 其他 数据结构和算法 java基础怎么学? 当时,作为懵懂的小白,大一学习了c和c++ ...
- Python基础之数据类型详解
为什么会有数据类型? 在介绍具体的数据类型之前,需要了解为什么需要区分数据类型.我们知道,一个公司会有很多个大的部门,每个部门下又会有许多细分的小部门,构成了公司的完整体系结构.如果把python的数 ...
- 为科学计算而生的Julia——基于Manjaro Linux的安装与入门
技术背景 Julia是一门为科学计算而生的编程语言,其着重强调了开源.生态与性能.从开源角度来说,相比于Matlab就要友好很多,用户可以免费使用,而且MIT协议应该是最宽松的开源协议之一(截图来自于 ...