CF1175F The Number of Subpermutations 【笛卡尔树,随机化】

题目描述:给个长度为 \(n\) 的序列 \(a\),求有多少个连续子排列(若长度为 \(l\) 则为 \(1,2,\dots,l\) 的排列)

数据范围:\(n\le 3\times 10^5\)

首先有个标准做法,用笛卡尔树的方式分治,知道最大值之后就知道了长度,用启发式分裂的方式(选择更短的半边)枚举。以枚举左半边为例,设 \(p_i=\max\{j|a_j=a_i\}\)\(pre_i=\max\limits_{j=1}^ip_j\),则 \([l,r]\) 没有重复数字当且仅当 \(pre_r<l\)。时间复杂度 \(O(n\log n)\)

还有个sd做法,给每个数随机一个 64 位数权值 \(b_i\)\(pre_i=\bigoplus\limits_{j=1}^ib_j\)。一个满足要求的子排列必须恰含一个 \(1\),我们枚举这个 \(1\) 的位置。不妨设最大值的位置在 \(1\) 后(前面可以把 \(a_i\) reverse 之后用同样的方法计算),然后枚举右端点,就知道了最大值和长度,看这一段的异或和是否为 \(pre_l\)。时间复杂度 \(O(n)\).

code

posted @ 2020-04-10 20:01  mizu164  阅读(137)  评论(0编辑  收藏  举报