构造 & 交互

一些方法论

大部分构造/交互题目都属于 ad-hoc 的类型,即难以转化为任何已知算法,所以更多时候我们需要通过猜测来解决这类问题。

当然猜测也是有方向的。一个很重要的想法就是,很多时候构造/交互状态空间会极其巨大,此时可以通过主动添加限制来寻找切入点,例如子集限制为区间,参数限制为常数等。当然也有可能变得更复杂,所以大范围的试错通常是有必要的。

此外还有一些常见技巧,如

  • 增量构造法。
  • 中转构造法,即选定中间状态 \(Q\),通过分别构造 \(A\to Q\) 和 \(Q\to B\) 得到 \(A\to B\)。
    进一步延伸可以得到类分治的做法,即考虑跨中点的路径使用中点作为中转点。
  • 分治/二分。
  • 猜结论(?

cf1882E1

容易想到的是把两个序列分开考虑,再考虑如何合并。

对于任意序列,先后操作 \(1,n\) 序列不变。

对于任意序列,操作 1 \(n\) 次序列不变。

对于长度为偶数的序列,任意操作必改变逆序对奇偶性。

考虑连续操作 \(x,y,x\) 可以交换 \(x,y\)。

那么仔细实现即可(?


p16325

首先,交换前后 \(p_x\oplus p_y\) 不变,则操作前/后可行性不变。

则对于任意可行操作序列 \(Q\),反转后 \(Q'\) 仍然合法。

由此,不妨取元排列 \(I\),并考虑如何构造 \(P\to I\)。

操作次数限制大约为 \(n\),即平均每次操作归位一个数。

考虑欲归位 \(p_x=y\),考察 \(p_y=z\) 的取值,希望交换 \(x,y\):

\[p_x\oplus p_y \le x\oplus y \]

由 \(p_x=y\),做换元有:

\[y\oplus p_y \le x\oplus p_x \]

取使得 \(x_0\oplus p_{x_0}\) 取得最大值的 \(x_0\),总是立即能归位。

堆维护即可


cf1270E

考虑如下构造:

alt text

记全局颜色数为 \(C\)。若 \(C\le k\),答案即为 \(k-C\)。

否则,取边长 \(L\) 最大的绿色正方形使得覆盖后颜色数 \(C'\ge k\),则边长 \(L+1\) 覆盖后的颜色数 \(C''<k\)。

对于红色正方形的边长取值 \(l\),当 \(l=0\) (红色正方形不存在)时有颜色数 \(c'=C'\),当 \(l=L+1\) 是有颜色数 \(c''=C''\),且有相邻的 \(l\) 的贡献的差值 \(\Delta c(l)\le 2\) 总成立。

这意味着对于 \(C''<k\le C'\),\(c=k\) 和 \(c=k-1\) 中至少有一个可行。通过调整红色正方形覆盖颜色为未出现过的颜色可以使 \(c\) 增加 \(1\),则总是可以在 \(2\) 以内可行。

计数答案考虑能够不出现红色正方形,即是否存在一个 \(L\) 使得 \(C'=k\) 恰成立,枚举边长 \(L\),对每种颜色维护二维差分,然后前缀和维护即可。


cf1270G

考虑设 \(a_i=i-t_i\),连边 \(i\to t_i\),则对于任意一个环,权值恰好相消,总和为 0。

又每个点恰好出度为 1,则其为内向基环树森林,必存在环。


cf715D

考虑在一个方案的基础上额外删去一个门,减少的方案数可以快速计算。

那么一个简单的贪心就是,从一个满的图开始,每次枚举使得方案数 \(t'\ge T\) 的 \(t'\) 最小的门并删去。

但是正确率只有一半,原因是有的时候删除的太激进了(?

那么一个好想法就是我们按 \(t'\) 从小到大每次以 \(\frac12\) 的概率接受,就有很大概率可以构造出来了。

实测可以做到 \(n,m\le 33,k\le 24\)。


qoj9432

考虑一个分治 solve(l,r,S),表示已知 \([l,r)\) 之内的数集为 \(S\)。

那么考虑如何把 \(S\) 划分为 \(S_0,S_1\)。

具体的,我们枚举每两个数 \(x,y\),考虑对询问,将 \([l,mid)\) 设为 \(x\),\([mid,r)\) 设为 \(y\),进行一次询问:

  • 若结果为 \(0/2\),则位置均已确定。
  • 若结果为 \(1\),则两数位于某同一侧。

对于第二种情况,可以类似并查集将 \(x,y\) 缩为一点,取一代表元参与后续询问。

考虑随机化选 \(x,y\) 的过程,有询问次数 \(f\) 满足

\[f(n)=\frac n4+f(\frac n4) \]

即 \(f(n)=\dfrac n3\),总询问次数 \(\dfrac n3\log n\)。


qoj15314

考虑 \(40\) 次询问差不多是 \(2.5 \log n\),我们考虑先用一次询问求出 \(X\) 的深度,记 \(c_u\) 表示 \(u\) 子树内可能成为 \(X\) 的 \(X'\) 的数量。

每次找到使得 \(|2c_u-c_1|\) 最小的 \(u\),询问并更新子树内/外的 \(c_u\),可以证明每次可以让答案集合变为原来的至多 \(\frac 23\)。

共询问 \(\log_2 n+\log_{\frac32}n\approx39\) 次。


cf2150E2

考虑判定一个数不是答案,即存在两次询问满足集合无交且均包含值 \(x\)。考虑在无交的基础上最大化概率,即得:

  • 取一个大小一半的随机子集 \(S\),记补集 \(\overline S\)。
  • 对每个数,若其被 \(S\) 和 \(\overline S\) 同时包含,则舍弃,概率 \(\frac12\)。
  • 重复上述过程,精细实现(skip 对 \(S\) 询问为 \(0\) 的结果)可以做到每个数每次 \(\frac74\) 次询问。

总询问次数 \(\frac72 n\)。

接着我们考虑一个惊为天人的优化:对于第一轮,不妨假设每个数均出现两次,同时维护*假设*情况下 \(S\) 和 \(\overline S\) 的*理论*大小,那么总有一个会矛盾,此时答案只有可能在另一侧,这将给出期望 \(\frac n4\) 的候选集大小。

总询问次数 \(\frac{21}8 n\),此时已经可以通过。

但是一个想法是,既然两次询问是非对称的,\(|S|=\frac12n\) 一定最优吗?不一定!事实上假如我们设 \(\frac{|S|}n=p\),由恰当的代数推导可得,取第一轮 \(p^*=0.446\),后续每轮 \(p'=0.414\),可取得询问次数最小值 \(2.577n\),提升约 \(1.8\%\)()

还有一个小优化是可以在第一次以后的轮次里仍然维护每个数属于左侧还是右侧,每次单侧递归,如果搜到解了直接返回。取 \(p=\frac12\) 可以做到 \(\frac{77}{32}n\approx2.406n\)。

在此基础上取第一轮 \(p^*=0.425,p'=0.439\),可以做到 \(2.357n\),有点丧心病狂了(x


cf1364E

记原序列为 \(a\)。

考虑找到 \(0\) 的位置 \(p_0\),那么只需 \(n-1\) 次询问即可问出所有数的值。那么还剩下 \(n+C\) 次询问,这里 \(C=175\)。

考虑对每个二进制位 \(k\),找出一个下标 \(q_k\) 使得 \(a_{q_k}\) 的第 \(k\) 位恰为 \(0\)。考虑每次随机两个数都有 \(\frac14\) 的概率至少找出一个 \(q_k\)。这一部分 \(4\log n\)。

那么我们可以在 \(\log n\) 次询问中求出一个位置的具体数值,具体地枚举 \(k\) 并查询和 \(q_k\) 的或结果。

接着,我们维护一个指针 \(t\),最终它会指向 \(0\) 的位置。初始令 \(t=1\),接着枚举每一个位置 \(i\),若有 \(a_i\mid a_t=a_t\),说明 \(a_i\subseteq a_t\),则用 \(i\) 替换 \(t\)。

这个过程最多只会发生 \(\log n\) 次,每次需要 \(\log n\) 的代价求出 \(a_t\) 的值,总共 \(\log^2 n\) 次询问。

由此即可解决原问题。


cf1764G3

大概是注意到只有 \(k=2,n\) 是有用的?后面都是比较针对性的优化了,没啥拓展性(x

posted @ 2026-09-22 18:18  CuteNess  阅读(22)  评论(1)    收藏  举报