NEFU大一暑假集训-线段树
- OP
- A Lowbit
* - B Ezzat and Grid
* - C 奇数国
* - D 敌兵布阵
* - E I Hate It
* - F Transformation
*
OP
感谢学长的讲解与付出;
感谢ph和zsl两位大佬的指导与讨论;
夹带私货:
此节课的代表性的内容已经整理到自己的贴子中:【笔记】数据结构
线段树本身相对抽象,一些题又有懒标记的要求,实在不太好理解;
从应用来讲,线段树可以快速地进行区间修改与区间查询,但是所需空间复杂度比较大,有时需要离散化处理;
A Lowbit
思路
朴素来讲,我们会在进行区间更改时递归到所有叶节点进行lowbit更改,但是这种做法会被卡T;
我们可以发现,若某叶节点元素 a 满足,则,并且的性质不会改变;
除此之外,若某节点 s 下所有叶节点元素 a 均满足,则对 s 区间进行操作后,等价与,并且的性质也不会改变;
我们可以用此性质,懒标记存储此节点有多少次二倍操作未下传,就可以一定程度上降低时间复杂度;
代码
1 |
|
B Ezzat and Grid
参考
线段树+dp
思路
首先左右界的数据范围过大,需要离散化处理;
定义dp函数为以第i行为末尾的最长可行序列长度,在线段树内存储结点下前i-1行该节点内的最大值;
对于某一行的若干的区间,假设有区间内的可行序列长度最大值为a,则有;
同时持续更新答案的最大值(即)即可;
但是此题要求输出应被删掉的点,就需要在维护线段树时同时记录该最大值对应的行号,在进行的修改时同时标记即可;
再通过上溯找到没有在这个序列中的点即可;
代码
1 |
|
C 奇数国
思路
朴素来讲,我们可以在维护乘积线段树的同时,用一个桶数组维护结点的乘积值内有什么质数,有;
但是如此存储的话,时间即为,约为,比较悬;
但是仔细观察,60个质数的存在性不必用数组维护,还可以用long long内的数位维护,用表示p结点下是否有质数,更新时变成了,时间复杂度降低啦;
最后结合快速幂和逆元进行欧拉函数值的求取即可;
代码
1 |
|
D 敌兵布阵
思路
板~
单点修改,区间查询
代码
1 |
|
E I Hate It
思路
板~
单点修改,区间查询
代码
1 |
|
F Transformation
思路
p\in\{1,2,3\}$$朴素来讲,我们可以使用三个懒标记和三个值维护未下传的区间加(ad),区间乘(mu),区间更改(cg)操作和区间下的元素和(sum1),元素平方和(sum2),区间立方和(sum3); 但是我们就面临一个问题,如果某位同时存在多种标记,如何判断它们的先后顺序? 在查阅资料时发现,有人在更新时选择先把当前结点的其他标记下传,但是被卡t了; 我们可以制定以下策略: 1. 对某结点进行cg操作时,直接修改三个sum值,清空ad和mu标记; 2. 对某结点进行mu操作时(假设区间乘d),维护三个sum值,对现有的ad标记乘d,mu标记也乘d; 3. 对某节点进行ad操作时(假设区间加d),通过 完全平方公式 和 完全立方公式 维护三个num值,对现有ad标记加d; 以此策略进行维护后,在下传懒标记时只需要以cg,mu,ad的顺序修改子节点就可以规避顺序问题; #### 代码1 |
|
1 |
|
1 |
|
NEFU大一暑假集训-线段树
https://tanyuu.github.io/2021.07-12/NEFU大一暑假集训-线段树/