【题解】Codeforces Round #769 (Div. 2)
B
构造题经常会卡一下... 这么考虑: 这题好像挺直球的( 首先考虑加一条边带来的影响,是由这两个点dist变小,做为“源点”更新出去的 情况 1,i 与 mid 的路径与 u, v 路径不相交,此时 i 与 mid 的距离必须不大于 mid 与 u, v 任意其一的距离,否则与距离最远矛盾
考虑最高位(设为d),一定存在两个相邻的数,最高位一个是1一个是0,异或起来答案就不会小于1<C
假设不使用操作3,那么答案就是b-a
假设使用操作3,用完后a>=b,接下来一直使用操作2令b自加1直到结束。为什么?因为每次使用操作1或3都会使a变得更大,而b只能通过自加1变大,所以接下来的最优方案就是一直用操作2
那么使用操作3之前的策略是什么呢?注意到b的总和不超过1e6,考虑枚举,既然要枚举,那就设元。假设a自加到a',b自加到b',那么答案就是 \(a'-a+b'-b+1+((a'|b')-b')=a'+(a'|b')+(1-a-b)\),考虑 \(a'+(a'|b')\),其中 \(a\leq a' < b \leq b'\)
\(a'\) 有范围,枚举 \(a'\):此时令 \(b'\) 大等于 \(b\) 且 \(a'|b'\) 尽量小
从高往低位考虑,,目标是在满足 \((a'|b')\) 尽量小的情况下,一旦满足 b'>b 就跑路
若当前位 1 = a' > b = 0,那 \(a'|b'\) 这一位肯定是 1 了,不妨直接当前位 b' 设为 1 满足 b'>b,之后的低位就全 0,然后break
否则的话,根据 a' 和 b 的情况讨论一下,然后继续考虑下一位D
注意到对于一个位置,一旦修改成一个足够大的未出现过的质数,那么它可以“切割”两边,即所有包含这个位置的区间的gcd都只会等于1
我们再设 f[i-1] = ans 表示前 i-1 个数的最小修改次数,以及上一个修改的位置是 p,那么对于当前的第 i 个数,我们只需要考虑区间 [p+1, i], [p+2, i], ..., [i, i]
注意到区间右端点不变,即r-l+1的r不变,而左端点往左扩时,gcd只会减小,r-l+1只会增大,两者最多一个交点,具有单调性,二分即可;若发现存在一个位置两者相等了,那么当前 i 修改,p 更新为 i,ans++
至于为什么不考虑当前位置 i 不修改而是去修改 i 之前的位置,因为 p 肯定越大越好,而且题面的条件是对任意子区间而言的E1, E2
但是真的是 两 个点吗?如果是,那么需要满足 dist[i]> dist[j]+x 和 dist[j]> dist[i]+x,显然不能同时满足,所以最多只有其中一个点 u 的dist变小,既然如此,那么另一个点肯定得是根节点
easy版本的一个做法,只需注意到对于一个固定的 u,随着 x 的减小,其能影响到的点在增多;所以枚举每个点 u 作为连线点:不考虑加边下,设以 1 为根的树上点 i 深度 d,以 u 为根树上点 i 深度 dd,则其满足 d> dd+x 时会被更新,所以把所有点按 d-dd 排个序,然后从大往小枚举 x 即可
hard版本,需要推出一个性质:假设对于一个深度 d,所有深度大于 d 的节点中距离最远的两个点,若加边使得这两个点的dist都小等于 d,则其他所有点的dist都会小等于 d
这是个什么道理?我想了一下,大概是这个原因:对于树上的一些被标记点,取其距离最远的两个点 u, v,考虑这两个点之间的路径上的任意一点 mid,接下来考虑任意标记点 i 与 mid 的距离,画图只有两个情况:
情况 2,i 与 mid 的路径与 u, v 路径相交,假设与 u, mid 一段相交,此时 i 与 mid 距离必须不大于 mid 与 u 的距离,否则矛盾
综上,回到题目,加边使得这两个点的dist小等于 d,显然需要把点加在两个点路径的中点处,假设两点距离 f,则需要满足:\(\lceil \frac{f}{2} \rceil+x\leq d\),此时其他点都满足dist小等于 d
对于一个固定的 d,我们求出对应的 \(f_d\),注意到随着d增大,\(f_d\) 是减小的;上式 x 单独移到一边,不等式另一边具有单调性,所以 d 作为答案具有单调性,二分答案或者双指针扫即可
\(f_d\) 怎么求?两个点之间的路径上肯定有其lca,通过lca求:对于每个点,求出其子树中最深和次深的两个 \(d_1, d_2\),则 \(f[d_2-1]=\max ( f[d_2-1], d_1+d_2-2d_{lca} )\),然后倒过来 \(f[d] = \max(f[d], f[d+1])\) 即可#include