Public Round #6
作者:互联网
报名打的为数不多的 PR,但是赛时经历及其惨痛(
T3 是通信所以没想去尝试,T1 想了 1h 大概知道是个乱搞但实在没有章法,T2 纯属降智了。
【PR #6】DNA 匹配
这个浮点答案的 checker 实现方式,以及 \(m\leq 40\) 的数据范围,很难不察觉这是一道偏乱搞题。
我的想法是 shuffle 之后强行截取前 \(20\) 个跑容斥,效果显而易见的不理想。
因为虽然串一多概率迅速变小,但是组合数也迅速变大,所以只考虑部分数据是不理智的。
正解用到一个叫 蒙特卡罗算法 的随机化技巧,实际就是 随机撒点求圆的面积 的原理。
但是纯随机看这个串能否被表示也是不够优秀的,因为当概率非常小时,得到的 \(\text{ans}\) 大概率是 \(0\)。
解决方法也不难,就是只针对某个串能够识别的字符串进行统计,最终概率再除以 \(n-\text{cnt}(?)\) 即可。
枚举一个串能识别的字符串,就是对着它的 \(?\) 位置随机,并非每个字符串都有贡献,因为可能同时会被其它字符串识别。
令当前串是 \(m\) 个中编号最小的能识别 \(s\) 的串时,\(s\) 才对当前串有贡献,贡献为 \(1\) 即可。
【PR #6】区间数颜色
发现如果一个区间 \(a\) 包含区间 \(b\),那么 \(b\) 一定在 \(a\) 之前被使用。
这个结论赛时我还以为自己能 hack,考虑两者剩余长度一样但 \(a\) 在编号上 \(>b\)。
实际上就是没看到条件,题目都说了长度随编号严格不降……
据此就比较明朗了,每次维护一个备选集合,其中没有相互包含的区间。
预处理的时候离散化得到 \(O(n)\) 段小区间,每次使用一个区间时,删除其中还未被删除的小区间。
这样,将集合中的区间按 \(l\) 排序(容易发现按 \(r\) 排序也一样) ,
就拥有一个非常好的性质:每次小区间影响到的区间是编号上连续的一段。针对没有包含关系区间的序列均有这一性质。
那就可以直接线段树维护了。
最后一个关键是使用完区间后,找到新晋的能够加入备选集合的区间。
发现可以找到区间 \(i\) 在当前备选集合中的前驱 \(j\) 和后继 \(k\),那么新备选区间的充要条件是在 \([L_j,R_k)\) 中。
初始将区间按照 \(L\) 升序排序,相当于每次在 \(>j\) 的编号中找 \(r<R_k\) 的区间,再用一棵线段树维护即可。
容易发现,这样更新会容许有 \(L\) 相等的区间同时在备选集合里,这是为了实现上的方便,而且不难发现上述性质并未被破坏。
赛时降智的点还不仅仅这些,赛后发现高分暴力全是 KD-tree,再稍加思考发现这个限制简直就是 KD-tree 的完美对象。
标签:PR,赛时,Round,集合,编号,区间,Public,备选 来源: https://www.cnblogs.com/lpf-666/p/16447494.html