其他分享
首页 > 其他分享> > Public Round #6

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