加加又赛赛 2
卡 CDQ 放莫队套值域分块,出题人你差不多得了,,,
A
双指针。
B
二分最大的 \(x\),使得和不超过 \(x\) 的子集小于 \(k\) 个,
check 时我们需要判断和不超过 mid 的子集是否小于 \(k\) 个,直接爆搜,搜出 \(k\) 个退出即可,
check 一次复杂度 \(O(k)\),总复杂度 \(O(k\log V)\)。
找出 \(x\) 后,爆搜出和不超过 \(x\) 的 \(c\) 个子集,从小到大输出后再输出 \(k-c\) 个 \(x+1\) 即可。
C
容易转化成求子矩阵内横坐标种类数,纵坐标种类数,莫队套值域分块即可。
顶针:能不能扩展一下做法。那就扩展一下做法。
现在的问题
给一个序列,每次询问 \(l,r,x,y\),求区间 \([l,r]\) 内,值在 \([x,y]\) 内的数的种类数。
在线做法
快进到强制在线
序列分块套值域分块
大家都会蒲公英吧?
对于任意两个块 \(i,j\),维护值域分块 \(c{i,j}\),\(c_{i,j,k}\) 表示 \(i,j\) 之间有没有数字 \(k\),
再维护 \(s_{i,j}\) 表示前 \(i\) 块中 \(j\) 的出现次数,
问 \(l,r,x,y\) 时,先对整块在 \(c\) 上查 \([x,y]\) 的和,再遍历散块中的每个值在 \([x,y]\) 内的数 \(v\),
若 \(v\) 在整块中没出现过(用 \(s\) 判断),在散块中也没遍历到过(开个桶判断),则 \(v\) 对答案有贡献。
取 \(B=n/\sqrt[3]q\) 即可做到 \(O(nq^{2/3})\)。
bitset
对每个块 \(i\) 维护 \(i\) 块的 bitset \(b_i\),对 \(b\) 建立按位或 ST 表。
询问时,先在 ST 表上查出整块的 bitset,再加入散块,然后提取 \([x,y]\) 即可。
取 \(B=\sqrt n\),瓶颈显然在每次询问需要 \(O(n/w)\) 查一次 ST 表,复杂度 \(O(nq/w)\)。
离线做法
你说得对但是这题不强制在线
莫队套值域分块
考虑莫队要维护什么,单点加删,查值在 \([x,y]\) 内的数的种类数,值域分块即可。
扫描线+(序列分块套值域分块/树套树/CDQ)
大家都会用树状数组做 HH 的项链吧?
考虑类似的做法,扫描序列,在颜色 \(i\) 的最后一次出现标记 \(i\),
序列分块套值域分块/树套树/CDQ
则对于询问 \(l,r,x,y\),答案为扫到 \(r\) 时区间 \([l,r]\) 内,值在 \([x,y]\) 内的数的个数,
发现这是带修二维偏序,序列分块套值域分块/树套树/CDQ 即可。
序列分块套值域分块/树套树/CDQ/bitset
考虑区间数颜色的另一种套路:维护 \(p_i\) 表示 \(a_i\) 上次出现的位置,
则 \([l,r]\) 中数的种类数为 \([l,r]\) 中 \(p_i<l\) 的数的个数。
则对于询问 \(l,r,x,y\),答案为区间 \([l,r]\) 中,值在 \([x,y]\) 内的数中 \(p_i<l\) 的数的个数。
发现这是三维偏序,序列分块套值域分块/树套树/CDQ/bitset 即可。
总共 10 种做法,量大管饱(