例 1. \(\text{CF1054E Chips Puzzle}\)

题目并未要求最小化步数,而且此题的操作可以进行倒退,于是我们可以构造一个简单的中间状态 —— \(1\) 全在 \((1,1)\)\(0\) 全在 \((2,1)\). 构造方式是先依靠列将 \(1/0\) 移动到指定行,再依靠行移动到指定点。

例 2. \(\text{CF468D Tree}\)

路径和优先考虑转化成深度(不妨设根的深度为零):

\[\begin{align} \sum_{i=1}^nd(i,p_i)&=\sum_{i=1}^n \text{dep}_i+\text{dep}_{p_i}-2\cdot\text{dep}_{\text{lca}(i,p_i)}\\ &=2\cdot \sum_{i=1}^n \text{dep}_i-2\cdot \sum_{i=1}^n \text{dep}_{\text{lca}(i,p_i)} \end{align} \]

现在需要最小化后面一坨柿子,事实上它是可以取到零的。不妨设入点代表 \(p_i\),出点代表 \(i\),这就转换成一个匹配问题 —— 能否将所有出/入点配对使得其 \(\rm lca\) 均为根节点?考虑证明,令子树 \(u\) 的出点个数为 \(\text{out}_u\),入点个数同理。那么考虑每棵子树(这里及之后的子树特指根的儿子统领的子树),必须在每时每刻都满足 \(\text{in}_u\le \sum \text{out}_i-\text{out}_u\) 也即 \(\text{in}_u+\text{out}_u\le \sum \text{out}_i=\sum \text{in}_i\). 之后我们将根也看作一棵大小为 \(1\) 的子树。

考虑初始状态有 \(\text{in}_u=\text{out}_u=\text{siz}_u,\sum \text{in}_i=n\),所以每棵子树需要满足 \(2\cdot \text{siz}_u\le n\),这不就是重心的定义吗?于是选取重心为根。

我们先阐述构造方式,最后给出严谨性的证明。由于要求字典序最小,所以从出点 \(1\) 开始往出点 \(n\) 匹配,每次尽量选择最小的点。假设匹配到第 \(i\) 个出点,那么 \(\sum \text{out}_i=n-i+1\).

  • 若存在 \(u\) 使得 \(\text{in}_u+\text{out}_u= \sum \text{out}_i\):此时必须保证 \(i,p_i\)有且只有 一个点在子树 \(u\). 所以若 \(i\) 不在子树 \(u\) 中,就必须选择子树 \(u\) 中最小的入点。需要注意的是,若 \(u\) 为根节点不用管这条限制。
  • 若不存在 \(u\) 使得 \(\text{in}_u+\text{out}_u= \sum \text{out}_i\),或者存在 \(u\) 使得 \(\text{in}_u+\text{out}_u= \sum \text{out}_i\)\(i\) 在子树 \(u\) 中:选择当前最小且与 \(i\) 不在同一子树的入点即可。

具体可以用 \(3\)\(\rm set\) 实现:一个维护最小入点,一个维护 \(\text{in}_u+\text{out}_u\),最后一个维护子树最小入点。

你可能会有一个疑惑,难道不会出现满足 \(\text{in}_u+\text{out}_u= \sum \text{out}_i\) 的子树有很多个,导致构造方式无法构造出合法解的情况吗?

事实上,可以证明至多有两棵子树满足以上条件,且其余子树均被匹配完,不妨设这两棵子树为 \(a,b\),那么有:

\[\text{in}_a+\text{out}_a=\text{in}_b+\text{out}_b= \sum \text{out}_i= \sum \text{in}_i \]

那么

\[\text{in}_a=\sum \text{out}_i-\text{out}_a\\ \text{out}_b=\sum \text{in}_i-\text{in}_b \]

接着有

\[\text{in}_a=\left(\sum \text{out}_i-\text{out}_a-\text{out}_b\right)+\sum\text{in}_i-\text{in}_b\\ \text{in}_a+\text{in}_b-\sum \text{in}_i=\sum \text{out}_i-\text{out}_a-\text{out}_b\ge 0 \]

所以有

\[\text{in}_a+\text{in}_b\ge \sum \text{in}_i \]

\[\text{in}_a+\text{in}_b= \sum \text{in}_i \]

同理也可以证得

\[\text{out}_a+\text{out}_b= \sum \text{out}_i \]

于是除开 \(a,b\) 两棵子树,其它子树均被匹配完。这也就意味着,此时我们只能分别匹配 \(a,b\) 两个子树的点,那么它们将保持 \(\text{in}_a+\text{out}_a=\text{in}_b+\text{out}_b= \sum \text{out}_i= \sum \text{in}_i\) 的状态一直到结束匹配!所以我们的构造一定合法。

例 3. \(\text{CF1329B Dreamoon Likes Sequences}\)

假设 \(a_i\) 的二进制位数为 \(c_i\),一个结论是 \(c_i\) 严格递增。证明可以用数学归纳法:首先由 \(a_{i}>a_{i-1}\)\(c_i\ge c_{i-1}\). 进行到 \(i=2\) 时,\(b_1\) 的最高位一定是 \(c_1\),所以若 \(c_i=c_{i-1}\),那么 \(b_2\) 最高位小于 \(c_1\),得出 \(b_2<b_1\)……归纳可得 "\(b_i\) 的最高位一定是 \(c_i\)" 的结论,那么上文的结论也就容易证明了。

由于是任意长度,我们可以直接算出每一种位数 \(a\) 的方案数,再将每一种位数相乘得到答案(第 \(i\) 位系数为 \(2^i+1\),即有和没有),最后不要忘记 \(n=0\) 的情况。

例 4. \(\text{P6196 }\)代价

首先一个结论是 "\(1\) 必须最后取",可以这样感性的思考:一定找不到比 \(1\) 更好的邻居了,所以删去 \(1\) 也无法找到更好的邻居。那么对于两端为 \(1\) 的非 \(1\) 段,从两端开始取,这个也可以进行感性的思考:整段的乘积个数是一定的,如果从两端开始取,意味着每个数字至多对两个乘积进行贡献。而对于其它的方案都无法保证这一性质。

例 5. \(\text{exchange your brains!}\)

例 6. \(\text{[AGC015D] A or...or B Problem}\)

先提一嘴,在翻这题的题解时看到了 \(\text{or,xor,and}\) 的一些转化,先放在这里:

\[a+b+(a\oplus b)=2\cdot(a\text{ and }b)+2\cdot (a\oplus b)=2\cdot (a\text{ or }b) \]


第一次看这道题可能会很乱,事实上可以先从 \(\rm or\) 运算的简单性质入手:只能变得更大。所以最后或出来的最小值一定为 \(l\). 由于 \([l,r]\) 已经获得,所以目标转化成 "拓展 \(r\)"。

自然地,我们选取 \(l\)\(r\) 第一个不相同的二进制位 \(\rm pos\)(之前相同的二进制位在最后的答案中是一定不可避免的,令其为 \(\rm base\)),令 \(z=\text{base}+2^{\rm pos}\). 考虑 \([l,z)\),显然与 \(z\) 或起来最大的区间是 \([z\mid l,z\mid (z-1)]\),并且 \(z\mid (z-1)\) 也是我们能够得到的最大数字;但是,\((r,z\mid l)\) 之间能不能新增新的数字呢?我们现在利用 \(z\)\((z,r]\) 之间的数字或起来:找到比 \(\rm pos\) 小的第一个 \(r\)\(1\) 的二进制位 \(j\),显然总存在 \(\text{base}+2^k\ \ (k\in[0,j])\) 这一系列数,用这些数可以组合出 \([\text{base},\text{base}+2^{j+1})\) 之间的所有数字,或上 \(z\),就能组合出 \([\text{base}+2^{\rm pos},\text{base}+2^{j+1}+2^{\rm pos})\) 的所有数字。这也是区间 \((z,r]\) 能贡献的极限了。

初始一定有 \([l,z)\),再将 \([\text{base}+2^{\rm pos},\text{base}+2^{j+1}+2^{\rm pos})\)\([z\mid l,z\mid (z-1)]\) 求并即可。

最后,可以自己想想为啥不将 \([l,z)\)\((z,r]\) 之间的数字或起来。

posted on 2020-06-01 21:19  Oxide  阅读(58)  评论(0)    收藏  举报