UVA1401 Remember the Word 字典树维护dp
题目链接:https://vjudge.net/problem/UVA-1401
题目:
Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie. Since Jiejie can’t remember numbers clearly, he just uses sticks to help himself. Allowing for Jiejie’s only 20071027 sticks, he can only record the remainders of the numbers divided by total amount of sticks. The problem is as follows: a word needs to be divided into small pieces in such a way that each piece is from some given set of words. Given a word and the set of words, Jiejie should calculate the number of ways the given word can be divided, using the words in the set.
Input
The input file contains multiple test cases. For each test case: the first line contains the given word whose length is no more than 300 000.
The second line contains an integer S, 1 ≤ S ≤ 4000. Each of the following S lines contains one word from the set. Each word will be at most 100 characters long. There will be no two identical words and all letters in the words will be lowercase. There is a blank line between consecutive test cases. You should proceed to the end of file.
Output
For each test case, output the number, as described above, from the task description modulo 20071027.
Sample Input
abcd
4
a
b
cd
ab
Sample Output
Case 1: 2
题意:
多组输入,首先给你一个长度最大为3e5的字符串s
然后给你一个整数n,后面给你n个长度最大为100的字符串str[i]
问你使用str组成s字符串有多少种方式
这里讲解一下样例:
abcd
4
a
b
cd
ab
那么abcd可以通过a+b+cd 或者 ab+cd 两种方式构成
题解:
dp方程很容易找到
dp[i]=(dp[i]+dp[j]) (i<j)
dp[i]表示构成s字符串的[i,len](这里我们把s字符串下标看作从1开始)这一个子串有多少种方式
那么我们就是需要找到有多少个j可以满足i的需求,因为如果dp[i]+=dp[j],那么s的子串[i,j-1]就需要是str字符串
中的一个才可以
那么暴力判断的话肯定就会TLE,这个时候我们使用字典树来维护
字典树建树的复杂度是O(n),n就是所有字符串的长度,在这里就是所有str字符串的长度,大致建树复杂度就是O(1e5)
另外在字典树上查找满足要求的j的时候,因为str最长为100,所以查找的复杂度最大也是100
那么所有复杂度就是O(1e5)+O(1e5*1e2)
代码:
/*
题意:
多组输入,首先给你一个长度最大为3e5的字符串s
然后给你一个整数n,后面给你n个长度最大为100的字符串str[i]
问你使用str组成s字符串有多少种方式 这里讲解一下样例:
abcd
4
a
b
cd
ab 那么abcd可以通过a+b+cd 或者 ab+cd 两种方式构成 题解:
dp方程很容易找到
dp[i]=(dp[i]+dp[j]) (i<j)
dp[i]表示构成s字符串的[i,len](这里我们把s字符串下标看作从1开始)这一个子串有多少种方式
那么我们就是需要找到有多少个j可以满足i的需求,因为如果dp[i]+=dp[j],那么s的子串[i,j-1]就需要是str字符串
中的一个才可以 那么暴力判断的话肯定就会TLE,这个时候我们使用字典树来维护
字典树建树的复杂度是O(n),n就是所有字符串的长度,在这里就是所有str字符串的长度,大致建树复杂度就是O(1e5)
另外在字典树上查找满足要求的j的时候,因为str最长为100,所以查找的复杂度最大也是100
那么所有复杂度就是O(1e5)+O(1e5*1e2) */ #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=3e5+10;
const int mod=20071027;
typedef struct Trie* TrieNode;
int dp[maxn],flag;
struct Trie
{
int sum;
TrieNode next[30];
Trie()
{
sum=0;
memset(next,NULL,sizeof(next));
}
};
void inserts(TrieNode root,char s[105])
{
TrieNode p = root;
int len=strlen(s);
for(int i=0; i<len; ++i)
{
int temp=s[i]-'a';
if(p->next[temp]==NULL) p->next[temp]=new struct Trie();
p=p->next[temp];
}
p->sum+=1;
}
void Del(TrieNode root)
{
for(int i=0 ; i<2 ; ++i)
{
if(root->next[i])Del(root->next[i]);
}
delete(root);
}
void query(TrieNode root,char s[105],int pos)
{
TrieNode p = root;
int len=strlen(s+1),ci=0;
for(int i=pos;i<=len;++i)
{
int temp=s[i]-'a';
if(p->next[temp]==NULL)
{
return;
}
else
{
p=p->next[temp];
}
ci++;
if(p->sum>0)
{
//printf("%d %d %d\n",pos,dp[pos],dp[pos+ci]);
dp[pos]+=dp[pos+ci];
dp[pos]%=mod;
}
}
}
char ss[maxn],str[105];
int main()
{
int n,p=0;
while(~scanf("%s",ss+1))
{
flag=0;
memset(dp,0,sizeof(dp));
TrieNode root = new struct Trie();
scanf("%d",&n);
for(int i=0 ; i<n; ++i)
{
scanf("%s",str);
inserts(root,str);
}
int len=strlen(ss+1);
dp[len+1]=1;
for(int i=len;i>=1;--i)
{
//printf("------------%d\n",i);
query(root,ss,i);
}
printf("Case %d: %d\n",++p,dp[1]);
Del(root);
}
return 0;
}
UVA1401 Remember the Word 字典树维护dp的更多相关文章
- Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)
题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp
D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...
- UVALive 3942 Remember the Word 字典树+dp
/** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5) ...
- UVALive 3942 Remember the Word(字典树+DP)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- 【HDU - 5845】Best Division(xor-trie、01字典树、dp)
BUPT2017 wintertraining(15) #7E 题意 把数组A划分为k个区间,每个区间不超过L长度,每一个区间异或和之和为S.现在求:S不超过X,区间个数的最大值. 且A是这样给你的: ...
- Codeforces GYM 100114 D. Selection 线段树维护DP
D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...
- 【8.26校内测试】【重构树求直径】【BFS模拟】【线段树维护DP】
题目性质比较显然,相同颜色联通块可以合并成一个点,重新建树后,发现相邻两个点的颜色一定是不一样的. 然后发现,对于一条链来说,每次把一个点反色,实际上使点数少了2个.如下图 而如果一条链上面有分支,也 ...
- 2019牛客暑期多校训练营(第二场)E 线段树维护dp转移矩阵
题意 给一个\(n\times m\)的01矩阵,1代表有墙,否则没有,每一步可以从\(b[i][j]\)走到\(b[i+1][j]\),\(b[i][j-1]\),\(b[i][j+1]\),有两种 ...
随机推荐
- Supervisord进程管家
Supervisord进程管家 Supervisord是一个守护进程的工具,当进程意外终止或服务器掉电起来后,希望进程能够自动运行,supervisord可以很好的为我们做这件事情.同时supervi ...
- LeetCode235 二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖 ...
- 根据业务摸索出的一个selenium代码模版(python)
前言 总算入行上班几个月了,不得不说业务是真的不消停啊.. 本人工作上经常遇到一种场景:为甲方做自动化接口处理工具,登录需要短信验证码,, 嘛算是摸索出了一套selenium代码模板,主要解决如下痛点 ...
- Kaggle泰坦尼克-Python(建模完整流程,小白学习用)
参考Kernels里面评论较高的一篇文章,整理作者解决整个问题的过程,梳理该篇是用以了解到整个完整的建模过程,如何思考问题,处理问题,过程中又为何下那样或者这样的结论等! 最后得分并不是特别高,只是到 ...
- oracle分区表分区栏位NULL值测试
实验在分区栏位为NULL时,分区表的反应 1.创建普通的分区表 CREATE TABLE MONKEY.TEST_PART_NULL_NORMAL ( ID NUMBER, ADD_DATE DATE ...
- SparkStreaming和Kafka基于Direct Approach如何管理offset实现exactly once
在之前的文章<解析SparkStreaming和Kafka集成的两种方式>中已详细介绍SparkStreaming和Kafka集成主要有Receiver based Approach和Di ...
- linux下安装nacos
一.安装 1.下载安装包: https://github.com/alibaba/nacos/releases 2.解压 : tar -xzvf nacos-server-1.2.1.tar.gz 3 ...
- 基于Python的接口自动化-unittest测试框架和ddt数据驱动
引言 在编写接口自动化用例时,我们一般针对一个接口建立一个.py文件,一条接口测试用例封装为一个函数(方法),但是在批量执行的过程中,如果其中一条出错,后面的用例就无法执行,还有在运行大量的接口测试用 ...
- GStreamer环境搭建篇
GStreamer是一套强大的多媒体中间件系统,跟FFmpeg功能类似. 各个Linux发行版(Ubuntu,fedora),大都集成了GStreamer相关工具,而作为软件层次结构最上层的播放器,几 ...
- 如何实现new,call,apply,bind的底层原理。
new做了什么? new是用来实例化对象的,当new了一个对象后 1.创建一个新对象 2.将构造函数的作用域赋值给新对象(this指向新对象) 3.执行构造函数里面的代码(为这个新对象添加属性) 4. ...