方差
令 为方差, 为区间和, 为区间平方和。
对区间平方和进行区间加
等差序列
对于 加上一个等差序列,令首项为 ,公差为 。可以发现等差序列公式和差分有点像,所以先进行差分,那么区间修改相当于在 加上 ,在 加上 ,在 加上 即可。那么查询操作是区间求和。
最长单调序列 逆序对
以最长不下降序列为例,维护一个权值线段树或树状数组,区间 为 的最长不下降子序列。正序扫,对每个数对桶进行区间最大值转移,再把这个数加进去更新。
逆序对同理,倒着扫,只不过区间最大值改成区间求和。
最大子段和
维护一个线段树,对于一个点表示的 ,有三类。一是左儿子的答案,二是右儿子的答案,三是左儿子的后缀与右儿子的前缀拼接。那么线段树要维护的是前缀,后缀还有区间和即可。
对于查询函数,如果当前区间被查询区间包括,返回当前区间答案。如果查询区间全部在当前节点的左儿子或右儿子内,直接递归左儿子或右儿子。否则是当前区间包括了查询区间,那么递归下去把左儿子和右儿子中的询问区间找出来,再讨论一下三类取最值。
P2824 排序
给定一个排列和若干个修改,每次修改将一段区间升序或降序排序。最后求 上的数字。
这真女少口阿。
用线段树来排序是不可能的,但可以用区间求和与区间修改模拟 01 序列的排序。而且只有最后的一次查询,那么 上的数字有没有单调性?先二分这个要查询的数试一试,让大于等于这个二分值的数为 ,小于的为 ,那么对每个询问对 01 序列的排序,如果最后位置 是 那么就减小二分值,为 则增大二分值,这当然有单调性了,就做完了,带了两个 。
P1712 区间
在一个数轴上有 个闭区间,选出 个区间使得它们包含至少同一个位置。求所有合法方案的最小区间长度极差。
哎,排序区间的长度好像没什么影响,那先排序。排序后好像可以尺取法,那么就一直选,选到有 个公共点时就停下来,再减少长度小的区间,直到减少了这个区间就 个公共点再停下来。那么选择的区间就是答案。
至于有多少个公共点,区间加求最大值即可。
P2633 Count on a tree
求一条树上给定的若干个路径上的第 小点权。
主席树 + 树链剖分
考虑一条链上的问题,每棵主席树都是一个的前缀中每个点权出现次数的桶,那么用前缀和的思想可以求出 每个数中出现的次数,再线段树二分一下即可。那么放到树上,可以将前缀和变成树上前缀和,用 lca 转一下就行。
HDU 6315 Naive Operations
给定一个排列 ,你需要维护一个初始全 的序列 ,支持 如下两种操作
- 区间加
- 查询区间 之和
直接求不方便,不然把给 换成给 ,如果减到了 就加一 ,再把把 赋值回来。可以维护一个区间最小值和区间和,最小值如果减成了 就暴力递归到叶子修改,因为 是排列,所以这个暴力的复杂度是调和级数不会超时。
二维数点
给定平面上 个点 每次问你一个矩形内有多少点。 允许离线。
用二维前缀和拆成四部分去维护,这是一个二维偏序问题,先对第一维排序,用线段树或树状数组去维护即可。
蚯蚓
给你一堆数,有 个,并对他们操作 次。每次取出最大的一个数 ,称之为母数。并将 分割成左端数 和右端数 ,并把这两个数放回数堆中,其余数均增加 。 固定为 的有理数。要求输出每次操作的数x和m次操作后所有数的和。
对于 的数据,是可以用优先队列搞的。我们用优先队列维护所有蚯蚓的长度,每次取出长度最长的蚯蚓,将其切成两半并丢回队列。有一个问题是如何让其他蚯蚓的长度增加 呢?可以记录蚯蚓整体增加的长度,对被切成两半的蚯蚓,将其长度 即可。
对于 的数据,数据范围不允许带 ,但是找规律可以发现一个隐藏的单调性,先切成两半的蚯蚓的一半,一定比后切成两半的蚯蚓对应的一半长。所以可以用三个队列分别维护没有被切的蚯蚓,被切成 的蚯蚓,和被切成 的蚯蚓,每次选出三个队列中最大的蚯蚓切一下再丢回对应队列中即可。
永恒的契约
食物链
动物王国中有三类动物 , 吃 , 吃 , 吃 。现有 个动物,以 编号。每个动物都是 中的一种,但是我们并不知道它到底是哪一种。
一个人按顺序说了
句话,第一种说法是 1 X Y
,表示
和
是同类。第二种说法是 2 X Y
,表示
吃
。但这
句话真假不明,当一句话满足下列任一条件,这句话就是假话,否则就是真话。
- 当前的话与前面的某些真的话冲突,就是假话;
- 当前的话中 或 比 大,或当前的话表示X吃X,就是假话。
求假话的总数。
并查集能维护连通性、传递性。比如朋友的朋友是朋友,朋友的敌人是敌人。但是,维护敌人的敌人是朋友就很难维护了,所以就有种类并查集的诞生。这道题有三个物种,于是我们给并查集开三倍的空间。对于每种生物,第一倍空间储存同类,第二倍储存猎物,第三倍储存天敌,我们不能确定每种生物是 还是 还是 ,知道生物的相对关系就够了。
讨论第一种话, 与 是同类,可以转换成 不吃 且 不吃 。如果有一点不满足,那么就是谎言。如果都满足,那么 的同类都是 的同类, 的天敌都是 的天敌, 的猎物都是 的猎物。再讨论第二种话, 吃 ,可以转换成 与 不是同类且 不吃 。如果有一点不满足,那么就是谎言。如皋港都满足,那么 的同类是 的天敌, 的天敌是 的猎物, 的猎物是 的同类。
Kinoman
有一个长度为
的序列
,有一个长度为
的价值序列
。选择一个区间
获得的价值是
问价值最大的区间的价值。
预处理出每个数在序列 中第一次的位置,和 在 中下一个出现的位置 。用线段树维护每个位置作为右端点的答案。首先预处理出以 为左端点的答案。当 时, 间答案 。而 间答案 。如果 不存在,可以看作是 。然后每次更新最大值。
练习题
给定一棵 个节点的树, 每个点 有权值 。有 个询问, 对于询问 , 分别输出树上从 到 的路径中, 权值小于 / 等于 / 大于 的点的数目。强制在线。
这是对树的查询,我们可以通过求 转换成对一条链的查询。套路地,对于一个点 ,我们维护一个权值线段树以维护一个桶 ,对于每一个在根到 路径上的点 ,令 。当然,我们不能对每一个点重新建立一棵线段树,这个线段树要支持单点修改和区间求和,区间求和求的是前缀和。我们可以先 dfs 一遍原来的树,在 dfs 的过程中建立主席树。
Mex
有一个长度为 的数组 。 次询问,每次询问一个区间内最小没有出现过的自然数。即求区间 mex。强制在线。
考虑建立权值线段树,维护每一个权值在原数组中最后一次出现的下标。对于查询操作 ,可以取出右端点所对应的主席树,并在树上二分查找下标小于 的最小权值即为答案。虽然 非常大,显然答案不会超过 ,所以不用离散化。