ARC 184 ABD

A

感谢某人以高水平获得了 8 发罚时。

显然分组。考虑 11 个分为一组,这样一个组里面就不可能全是假币。然后对于每一组,让其中第一个元素去问另外 10 个元素。花费次数:\((1000/11)*10=910\) 次。(注意最后一组只有 10 个,要特殊处理)

如果一个组里面回答都是 0 的话,肯定就都是真币了,直接不管。考虑有 1 的情况,那么一定有假币。

发现很暴力啊,你先把组内第一个元素和外面随便一个是真的元素问 1 次(之前那些全是真币的组任选一个),就可以得到这个元素是真是假,再根据之前的组内询问就可以直接推出组内所有币的真假。

考虑最后 1 组,可能全部返回 0 但全部是假币,这个可以当其它组都是真币时直接推出,其余情况还是一样的。

所以一共只需要问 \(919\) 次(后面问 9 次就知道最后一个的情况了),当然还可以优化到 909。

B

第一道轮廓线 dp。

前置知识:集合选数。

我们考虑以每个 \(i\) 作为矩阵的第一项,构造出一个 \(\log_2 n\times \log_3\) 的矩阵。显然不同的 \(i\) 形成的矩阵都是独立的,即里面没有重复元素。

对一个矩阵单独考虑,我们对每一行状压,由于列数是 \(\log_3 n\),所以状压过后是 \(n^{2/3}\),可以接受。

发现普通的状压无法转移,所以我们需要轮廓线,题目的操作在矩阵中就是操作点 \((x,y)\) 使得点 \((x,y),(x+1,y),(x,y+1)\) 都被选中。

方程式很简单,最后返回选完所有数的答案即可。

然而还要优化,因为这种矩阵太多了。发现这个矩阵的大小是由 \(n/x\) 下取整决定的,如果这个值一样那么所有 \(x\) 所构造出来的矩阵大小都是一样的,只计算一次即可,这类似于整除分块。

时间复杂度我不会算,以及我实现较劣,时限 8s 我跑了 7.8s。

D

为什么场上会一直想区间 dp 呢。

这题的难点在于如何避免算重,我们需要加强对状态的限制

考虑 dp 操作序列(显然顺序不影响,所以按 x 升序进行 dp),令 \(dp_i\) 表示对 \(i\) 进行操作,并枚举上一个操作的位置 \(j(j<i)\) 转移过来。

如何避免不会算重?这里我们再限制:对于当前的操作序列,如果再操作任意一个球都会改变剩下的球。非常妙,使我想不到。

这样设计过后,所有剩下球的状态都会对应唯一的 dp 状态中的操作序列(尽管 dp 中某次操作没有改变剩下的球),两者形成双射。

然后就是转移条件了:(\(j<i\),把下标当成 x 轴)

  • 保证每个球都可以被操作,不存在操作一次球之后把其他待操作的球弄没了的情况:\(a_j>a_i\)。这里的结论是操作序列按下标排序后 \(y\) 值是单减的。

  • 由于 \((j,i)\) 内的球都没有操作,所以根据定义的限制,要判断是否所有的 \(k(j<k<i)\),它操作过后都会改变剩下的球。当然为了保证 \(k\) 可以操作,还要 \(k\) 满足 \(a_j>a_k>a_i\)

状态线性,枚举转移点线性,判断是否可以转移线性,时间复杂度为 \(O(n^3)\)。当然这东西显然可以大大优化,不讨论。


代码:

A:https://atcoder.jp/contests/arc184/submissions/58077662

B:https://atcoder.jp/contests/arc184/submissions/58087498

D:https://atcoder.jp/contests/arc184/submissions/58079618

posted @ 2024-09-24 22:17  LCat90  阅读(6)  评论(0编辑  收藏  举报