2019 年电子科技大学 ACM-ICPC 暑假前集训数据结构专题解题报告
14/15/15
讲之前 14/15,之后补完了。
A. 方差
题目描述
维护一个数据结构,支持区间加法,区间乘法,区间置为同一个数,询问区间方差。
数据范围:
题解
考虑方差公式:
对于区间内部,考虑用完全平方公式展开,后代入平均值,即:
要输出的答案为
因此,我们需要维护的是区间平方和和区间和。因此考虑用线段树解决。
对于区间加法,设区间
那么增量即为
对于区间乘法,设区间
对于区间置同一个数
对于询问,直接查询区间和与区间平方和即可。
就这样,我们可以在只打两个标记的情况下完成维护三个修改操作了。
时间复杂度
代码见这里
B. 吞吐量
题目描述
对于一棵有边权的树,多次询问两点间路径权的最小值。
数据范围:
题解
本题有一个显而易见的暴力做法,即每次从
考虑用倍增思想优化,预处理出每个点向上跳
事实上,上面写的可以用一句话概括:LCA。
(当然还可以写 RMQ-LCA)
(其实我也不知道为啥我把 LCA 讲了出来……)
时间复杂度:
原题详见:
类似题目详见:
(当然上面那道题主要是 Kruskal 重构树……)
代码见这里
C. 人在地上走,锅从天上来
题目描述
原来一条线段均为白色,每次对一个区间染黑,问有多少个黑色区间。
数据范围:
题解
对于区间染色问题,可以考虑用线段树方法实现。但是本题合并不满足区间可加性,因此需要增加维护的信息。
对于一个区间
需要注意的是,可能会有染色区间为一个点的情况,这时候需要维护单点。因此修改分为单点修改和区间修改即可。或者线段树区间写为左闭右闭即可。
对于
时间复杂度
代码见这里
D. 密码
题目描述
对于一个数列,留下
数据范围:
题解
对于保留
对于保留
对于求最大值,原题采用的是最近下降点优先删除的策略,那么这里将其反过来,采用最近上升点优先删除的策略即可,我们可以用单调栈快速实现,并且代码十分简单。
时间复杂度
代码见这里
E. 冬马和纱天下第一
题目描述
给出一个数列,问
转化题意,因为可以数字重排,于是我们可以统计这个区间的数字出现次数,为了使严格上升的序列最少,我们需要把出现最多的数字安排进每一个对答案有贡献的序列里,如果出现次数最多的数字都被安排进贡献中,那么出现次数少的数字一定可以全部被安排完毕。因此答案即为出现次数最多的数字的出现次数,即区间众数的出现次数。
因此最终题意为:多次询问区间内数字出现最多的次数,强制在线。
数据范围:
题解
对于在线求解区间众数问题,已经有成熟的
时间复杂度
原题详见:BZOJ 2724. [Violet 6] 蒲公英
代码见这里
F. 我永远喜欢冬马和纱
题目描述
同 E 题,但是本题允许离线。
数据范围:
题解
本题也可以像上一题一样分块求解,时间复杂度为
正确解法是采用莫队算法。需要统计一个区间内数字出现的次数和出现次数的次数,这些都可以在 while
循环,没有超出时间限制。
但是时限确实卡得有点紧……而且莫队跑得比带一个
事实上,分块最大的问题在于空间上过不去,但是因为 OJ 对于空间限制有 Bug 并没有 MLE……
时间复杂度
代码见这里
G. 线段树教做人
题目描述
维护一个数据结构,支持维护单点加,修改数列相邻两项差不小于
数据范围:
题解
首先我口胡了一个差分,结果被 Decision 大爷暴过去了。详细过程见 Decision 大爷的题解。
我目测这个差分不是那么好差的,但是我还在线段树上维护六个东西的时候,Decision 大爷说「暴力」。
然后我线段树维护就地爆炸……
首先我们有两个数组
这个柿子看起来不好吃看,主要原因是左边一个
记
令
对于查询操作,我们查询
时间复杂度
代码见这里
H. 拍照
题目描述
对于一个数列,求区间长度小于等于
数据范围:
题解
对于本题,有一个显而易见的动态规划解法。设
对于暴力转移,时间复杂度为
时间复杂度
注意边界,否则会 WA 在最后一个点上。
实际上,本题可以用单调队列优化求区间最小值的过程,时间复杂度可降至
代码见这里
I. 排名
题目描述
维护一个数据结构,支持动态插入,删除元素,并查询元素的排名。
数据范围:
题解
本题的元素虽然不是一个整数,但是是全序关系,可以进行比较。
需要维护的操作是平衡树可以完成的,但是不能用 set
,因为 set
查询元素排名是
修改一个元素可以看做先删除原来的元素,进行修改后再插入进去。
时间复杂度
代码见这里
J. 种海带
题目描述
求一个环上选择
数据范围:
题解
对于
对于有解的情况,如果不考虑相邻,可以考虑用堆贪心,但是需要考虑不相邻这一限制条件。可以发现,要么是一个最大值计入对答案的贡献,要么是最大值两边的元素和计入对答案的贡献。即最大值两边元素和大于最大值或小于等于最大值。这样我们就需要撤销之前的贪心操作,因此在维护时,记录一个点之前的点和之后的点,每次取最大值时将其前驱后继删除,并把这点权值改为两边权值和减去原该点权值,再把它插入堆中。这样如果该点被再次查到,那么就是需要将最大值两端计入贡献中的情况,并且可以保证不相邻。
时间复杂度
代码见这里
K. 对答案
题目描述
给出一些连续子串和的奇偶性,判断是否能满足要求。
数据范围:
题解
本题可以将子串分为两类,子串和为奇数或偶数。考虑到子串和不方便维护,我们可以维护前缀和,子串和即为两个前缀和之差,即
我们可以讨论 ORZQHQH
。
时间复杂度
原题来自:POJ 1733. Parity Game(为原题弱化)
代码见这里
L. 我的题面最简单,快来做!
题目描述
维护一个数据结构,支持区间加两段等差数列(组合起来为山峰形),求区间最长等差数列长度。
数据范围:
题解
对于区间求最长等差数列长度,可以维护这个数列的一阶差分数组,转化为区间最长相同数字的长度,也可转化为二阶差分维护区间最长
对于维护最长相同数字长度,这个可以如同 C 题一样维护区间左右端点数字,区间左起最长连续数字长度,区间右起最长连续长度,区间内数字是否均相同和区间内部答案。通过考虑左区间的右端点和右区间的左端点即可合并答案。
线段树维护不容易合并的东西一般都需要维护左右端点信息以及类似信息,如同 SPOJ GSS 系列题一样。
虽然二阶差分可以做到只进行单点修改来完成操作,但是理论上推的是对的,但是实际上 WA on test 1……
然后就是本题重点不用 LaTeX 导致 WA 20 多次……(眼睛不需要可以捐给需要的人)
(反正这里是熊猫头,下面是脏话)
UPD:Gaw4Gura 大哥用二阶差分过了,在这里。我也不知道我二阶挂哪儿了,估计是合并答案错了……
时间复杂度
代码见这里
M. My description is the most 単純な one,come on!
题目描述
给定一个树,树的节点非红即蓝,初始只有
数据范围:
题解
很显然的一个想法是 LCT,因为这棵树是动态的……但是不会 LCT 作罢。
考虑利用动态树分治来进行求解,我们保存树分治时所有求出的重心,可以建立一棵深度不超过
本题中查询树上距离为基本操作,普通的倍增求距离会导致复杂度过高而超出时间限制,因此需采用 RMQ-LCA 将询问两点间距离的复杂度优化至
对于修改操作,单次时间复杂度为
原题详见:SPOJ QTREE5
代码见这里
N. 数理统计
题目描述
维护一个数据结构,支持区间加法,查询区间和,区间极差。
数据范围:
题解
对于本题,可以直接利用线段树解决。维护区间和,区间最大值和区间最小值即可。易知上述三个维护项均具有区间可加性,区间加法也可以利用打标记降低复杂度。
时间复杂度
代码见这里
O. 战争
题目描述
维护一个数据结构,支持插入一个数,删除一个数,查询
数据范围:
题解
因为异或运算只与二进制本位有关,不会向下一位进位,因此可以分开考虑其对答案的贡献。
事实上,对于本题有经典的 Trie 树方法维护。把一个数的二进制当做字符串插入 Trie 树中,插入删除操作同 Trie 树操作,询问时,每次贪心地维护答案即可。
时间复杂度
代码见这里