20ZR暑期集训 简单数据结构

方差

D D D 为方差, S S S 为区间和, S 2 S_2 S2 为区间平方和。

D = 1 r − l + 1 ∑ i = 1 r ( a i − S r − l + 1 ) 2 = 1 r − l + 1 ∑ i = 1 r ( a i 2 − 2 S a i r − l + 1 + S 2 ( r − l + 1 ) 2 ) = 1 r − l + 1 ( S 2 − S 2 ) \begin{aligned} D &=\frac{1}{r-l+1} \sum_{i=1}^{r}\left(a_{i}-\frac{S}{r-l+1}\right)^{2} \\ &=\frac{1}{r-l+1} \sum_{i=1}^{r}\left(a_{i}^{2}-\frac{2 S a_{i}}{r-l+1}+\frac{S^{2}}{(r-l+1)^{2}}\right) \\ &=\frac{1}{r-l+1}\left(S_{2}-S^{2}\right) \end{aligned} D=rl+11i=1r(airl+1S)2=rl+11i=1r(ai2rl+12Sai+(rl+1)2S2)=rl+11(S2S2)

对区间平方和进行区间加

S 2 ′ = ∑ i = l r ( a i + v ) 2 = ∑ i = l r ( a i 2 + 2 v a i + v 2 ) = S 2 + 2 v S + ( r − l + 1 ) v 2 \begin{aligned} S_{2}^{\prime} &=\sum_{i=l}^{r}\left(a_{i}+v\right)^{2} \\ &=\sum_{i=l}^{r}\left(a_{i}^{2}+2 v a_{i}+v^{2}\right) \\ &=S_{2}+2 v S+(r-l+1) v^{2} \end{aligned} S2=i=lr(ai+v)2=i=lr(ai2+2vai+v2)=S2+2vS+(rl+1)v2

等差序列

对于 l ∼ r l \sim r lr 加上一个等差序列,令首项为 a a a,公差为 D D D。可以发现等差序列公式和差分有点像,所以先进行差分,那么区间修改相当于在 l l l 加上 a a a,在 ( l , r ] (l,r] (l,r] 加上 D D D,在 r + 1 r+1 r+1 加上 − a − D × ( r − l ) -a-D \times (r - l) aD×(rl) 即可。那么查询操作是区间求和。

最长单调序列 逆序对

以最长不下降序列为例,维护一个权值线段树或树状数组,区间 [ l , r ] [l,r] [l,r] a i ∈ [ l , r ] a_i \in [l,r] ai[l,r] 的最长不下降子序列。正序扫,对每个数对桶进行区间最大值转移,再把这个数加进去更新。

逆序对同理,倒着扫,只不过区间最大值改成区间求和。

最大子段和

维护一个线段树,对于一个点表示的 [ l , r ] [l,r] [l,r],有三类。一是左儿子的答案,二是右儿子的答案,三是左儿子的后缀与右儿子的前缀拼接。那么线段树要维护的是前缀,后缀还有区间和即可。

对于查询函数,如果当前区间被查询区间包括,返回当前区间答案。如果查询区间全部在当前节点的左儿子或右儿子内,直接递归左儿子或右儿子。否则是当前区间包括了查询区间,那么递归下去把左儿子和右儿子中的询问区间找出来,再讨论一下三类取最值。

P2824 排序

给定一个排列和若干个修改,每次修改将一段区间升序或降序排序。最后求 p p p 上的数字。

这真女少口阿。

用线段树来排序是不可能的,但可以用区间求和与区间修改模拟 01 序列的排序。而且只有最后的一次查询,那么 p p p 上的数字有没有单调性?先二分这个要查询的数试一试,让大于等于这个二分值的数为 1 1 1,小于的为 0 0 0,那么对每个询问对 01 序列的排序,如果最后位置 p p p 1 1 1 那么就减小二分值,为 0 0 0 则增大二分值,这当然有单调性了,就做完了,带了两个 log ⁡ \log log

P1712 区间

在一个数轴上有 n n n 个闭区间,选出 m m m 个区间使得它们包含至少同一个位置。求所有合法方案的最小区间长度极差。

哎,排序区间的长度好像没什么影响,那先排序。排序后好像可以尺取法,那么就一直选,选到有 ≥ m \ge m m 个公共点时就停下来,再减少长度小的区间,直到减少了这个区间就 < m <m <m 个公共点再停下来。那么选择的区间就是答案。

至于有多少个公共点,区间加求最大值即可。

P2633 Count on a tree

求一条树上给定的若干个路径上的第 k k k 小点权。

主席树 + 树链剖分

考虑一条链上的问题,每棵主席树都是一个的前缀中每个点权出现次数的桶,那么用前缀和的思想可以求出 [ l , r ] [l,r] [l,r] 每个数中出现的次数,再线段树二分一下即可。那么放到树上,可以将前缀和变成树上前缀和,用 lca 转一下就行。

HDU 6315 Naive Operations

给定一个排列 b b b,你需要维护一个初始全 0 0 0 的序列 a a a,支持 如下两种操作

  • 区间加 1 1 1
  • 查询区间 ⌊ a i b i ⌋ \left\lfloor \frac{a_{i}}{b_{i}} \right\rfloor biai 之和

直接求不方便,不然把给 a i + 1 a_i + 1 ai+1 换成给 b i − 1 b_i - 1 bi1,如果减到了 0 0 0就加一 ,再把把 b i b_i bi 赋值回来。可以维护一个区间最小值和区间和,最小值如果减成了 0 0 0 就暴力递归到叶子修改,因为 b b b 是排列,所以这个暴力的复杂度是调和级数不会超时。

二维数点

给定平面上 n n n 个点 ( x i , y i ) , \left(x_{i}, y_{i}\right), (xi,yi), 每次问你一个矩形内有多少点。 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^{5} 1n105 允许离线。

用二维前缀和拆成四部分去维护,这是一个二维偏序问题,先对第一维排序,用线段树或树状数组去维护即可。

蚯蚓

给你一堆数,有 n n n 个,并对他们操作 m m m 次。每次取出最大的一个数 x x x,称之为母数。并将 x x x 分割成左端数 [ x × p ] [x \times p] [x×p] 和右端数 x − [ p × x ] x-[p \times x] x[p×x],并把这两个数放回数堆中,其余数均增加 q q q p p p 固定为 ( 0 , 1 ) (0,1) (0,1) 的有理数。要求输出每次操作的数x和m次操作后所有数的和。

对于 85 % 85\% 85% 的数据,是可以用优先队列搞的。我们用优先队列维护所有蚯蚓的长度,每次取出长度最长的蚯蚓,将其切成两半并丢回队列。有一个问题是如何让其他蚯蚓的长度增加 q q q 呢?可以记录蚯蚓整体增加的长度,对被切成两半的蚯蚓,将其长度 − q -q q 即可。

对于 100 % 100\% 100% 的数据,数据范围不允许带 l o g log log,但是找规律可以发现一个隐藏的单调性先切成两半的蚯蚓的一半,一定比后切成两半的蚯蚓对应的一半长。所以可以用三个队列分别维护没有被切的蚯蚓,被切成 [ x × p ] [x \times p] [x×p] 的蚯蚓,和被切成 x − [ p × x ] x- [p \times x] x[p×x] 的蚯蚓,每次选出三个队列中最大的蚯蚓切一下再丢回对应队列中即可。

永恒的契约

食物链

动物王国中有三类动物 A , B , C A,B,C A,B,C A A A B B B B B B C C C C C C A A A。现有 N N N 个动物,以 1 ∼ N 1 \sim N 1N 编号。每个动物都是 A , B , C A,B,C A,B,C 中的一种,但是我们并不知道它到底是哪一种。

一个人按顺序说了 K K K 句话,第一种说法是 1 X Y,表示 X X X Y Y Y 是同类。第二种说法是 2 X Y,表示 X X X Y Y Y。但这 K K K 句话真假不明,当一句话满足下列任一条件,这句话就是假话,否则就是真话。

  1. 当前的话与前面的某些真的话冲突,就是假话;
  2. 当前的话中 X X X Y Y Y N N N 大,或当前的话表示 X X X X X X,就是假话。

求假话的总数。

并查集能维护连通性、传递性。比如朋友的朋友是朋友,朋友的敌人是敌人。但是,维护敌人的敌人是朋友就很难维护了,所以就有种类并查集的诞生。这道题有三个物种,于是我们给并查集开三倍的空间。对于每种生物,第一倍空间储存同类,第二倍储存猎物,第三倍储存天敌,我们不能确定每种生物是 A A A 还是 B B B 还是 C C C,知道生物的相对关系就够了。

讨论第一种话, X X X Y Y Y 是同类,可以转换成 X X X 不吃 Y Y Y Y Y Y 不吃 X X X。如果有一点不满足,那么就是谎言。如果都满足,那么 X X X 的同类都是 Y Y Y 的同类, X X X 的天敌都是 Y Y Y 的天敌, X X X 的猎物都是 Y Y Y 的猎物。再讨论第二种话, X X X Y Y Y,可以转换成 X X X Y Y Y 不是同类且 Y Y Y 不吃 X X X。如果有一点不满足,那么就是谎言。如果都满足,那么 X X X 的同类是 Y Y Y 的天敌, X X X 的天敌是 Y Y Y 的猎物, X X X 的猎物是 Y Y Y 的同类。

Kinoman

有一个长度为 n n n 的序列 f , f i ∈ 1 ∼ m f,f_i \in 1 \sim m f,fi1m,有一个长度为 m m m 的价值序列 w w w 。选择一个区间 [ l , r ] [l,r] [l,r] 获得的价值是
∑ i = l r w f i × [ c o u n t ( f i ) = 1 ] \sum_{i=l}^r w_{f_i} \times [count(f_i)=1] i=lrwfi×[count(fi)=1]
问价值最大的区间的价值。

预处理出每个数在序列 f f f 中第一次的位置,和 f i f_i fi f f f 中下一个出现的位置 n x t nxt nxt。用线段树维护每个位置作为右端点的答案。首先预处理出以 1 1 1 为左端点的答案。当 l + 1 l + 1 l+1 时, [ l , n x t i − 1 ] [l, nxt_i - 1] [l,nxti1] 间答案 − w f l -w_{f_l} wfl。而 [ n x t i , n x t n x t i − 1 ] [nxt_i, nxt_{nxt_i} - 1] [nxti,nxtnxti1] 间答案 + w f i +w_{f_i} +wfi。如果 n x t nxt nxt 不存在,可以看作是 n + 1 n + 1 n+1。然后每次更新最大值。

练习题

给定一棵 N N N 个节点的树, 每个点 i i i 有权值 a i a_i ai。有 Q Q Q 个询问, 对于询问 x , y , k x,y,k x,y,k , 分别输出树上从 x x x y y y 的路径中, 权值小于 / 等于 / 大于 k k k 的点的数目。强制在线。

这是对树的查询,我们可以通过求 l c a lca lca 转换成对一条链的查询。套路地,对于一个点 x x x,我们维护一个权值线段树以维护一个桶 b b b,对于每一个在根到 x x x 路径上的点 y y y,令 b a y + + b_{a_y}++ bay++。当然,我们不能对每一个点重新建立一棵线段树。这个线段树要支持单点修改和区间求和,区间求和求的是前缀和。我们可以先 dfs 一遍原来的树,在 dfs 的过程中建立主席树。

Mex

有一个长度为 n n n 的数组 a 1 ∼ n a_{1 \sim n} a1n m m m 次询问,每次询问一个区间内最小没有出现过的自然数。即求区间 mex。强制在线。

考虑建立权值线段树,维护每一个权值在原数组中最后一次出现的下标。对于查询操作 [ l , r ] [l,r] [l,r] ,可以取出右端点所对应的主席树,并在树上二分查找下标小于 l l l 的最小权值即为答案。虽然 a i a_i ai 非常大,显然答案不会超过 n n n,所以不用离散化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值