8 月杂题记
AT_joisc2017_c
题目描述:过于复杂,略。
答案明显具有单调性。考虑二分答案。
有一个很自然的想法,没点燃的要向正在燃的靠近,且一定以最大速度走 \(T\) 秒。
对于一个区间 \([L,R]\),满足让它能用一个点燃的互相点燃。有一个条件为 \(X_r - X_l \le 2 \times (r - l) \times v \times T\),转变一下,即为 \(X_r - 2 \times r \times v \times T \le X_l - 2 \times l \times v \times T\)。
我们就设 \(a_i = X_i - 2 \times i \times v \times T\)。
利用归纳法,要使 \([L,R]\) 合法,\([L+1,R]\) 或 \([L,R-1]\) 就需要合法。
我们找到一个性质最好的区间 \([L,R]\) 满足 \(L \le k \le R\) 且 \(a_L\) 最大,\(a_R\) 最小。
我们考虑 \([k,k]\) 扩展到 \([L,R]\)。
假设当前在 \([l,r]\),先考虑扩展 \(l\),到[i,r]。
- \(L \le i \le l \wedge a_l \le a_i\)。
- \(i \le j \le l \wedge a_j \ge a_r\)
其他情况同理。
若不能到 \([L,R]\) 则返回 \(0\)。
最后,我们将 \([1,n]\) 缩小到 \([L,R]\) 即可,与上面同理。
[PKUWC2018] Minimax
题目大意:给你一棵树,保证一个结点至多有两个子节点。给你叶子结点的权值。其余结点的值为 \(p_i\) 的概率为它子节点的最大值,\(1 - p_i\) 的概率为它子节点的最小值。设 \(1\) 号结点的权值有 \(m\) 种,第 \(i\) 小的值的概率为 \(D_i(D_i > 0)\),求 \(\sum_{i = 1}^{m} i\times D_i \times Val_i\)。
设 \(f_{i,j}\) 表示 \(i\) 结点值为 \(j\) 的概率。
则 \(f_{i,j} = f_{ls,j} \times (\sum_{k=1}^{j-1} f_{rs,k} \times p_i + \sum_{k=j+1}^{n} f_{rs,k} \times (1 - p_i)) + f_{rs,j} \times (\sum_{k=1}^{j-1} f_{ls,k} \times p_i + \sum_{k=j+1}^{n} f_{ls,k} \times (1 - p_i))\)。
我们可以在线段树合并中维护。
细节比较多。
[HEOI2016/TJOI2016] 排序
很有趣的题。
题目大意:给你个排列。做 \(m\) 次排序,给区间 \([l,r]\),让你按逆序或正序排,求最后 \(q\) 上的位置。
本身不好想。考虑简化,只有 \(0|1\)。设 \(cnt1\) 为区间内 \(1\) 的个数。则正序即为将 \(l \sim cnt1 - 1\) 变为 \(0\),\(cnt1 \sim r\) 变为 \(1\)。逆序同理。那么,使用线段树维护即可。
回到本题。想办法,将序列变为 \(0|1\)。那么,枚举 \(a_q\) 为多少。按大小转化为 \(0|1\)。若 \(a_q\) 转化后最后为 \(1\),则合法。
可以注意到具有单调性,二分即可。
[POI2011] ROT-Tree Rotations
题目大意:给一个 \(n\) 个叶子结点的二叉树。叶子结点有权值 \(p_i\),\(p\) 是一个排列。保证一个结点有 \(0|2\) 个儿子。你可以交换若干个结点的左右子树,求最后按先序排列后,叶子结点构成的序列逆序对的最小数量。
容易发现,交换一个结点,只对子树内的逆序对产生影响。
我们考虑交换一个结点后,逆序对的变化。设原来右子树对左子树的逆序对数量为 \(a\),左子树大小 \(sz_{ls}\),右子树大小 \(sz_{rs}\)。那么交换后,逆序对有 \(b = sz_{ls} * sz_{rs} - a\) 个。我们只需求出 \(a,b\),答案加上较小的一个即可。线段树合并就可以处理出逆序对数。只需在合并时求即可。
[AGC002D] Stamp Rally
题目大意:给一个连通图。\(q\) 次询问。每次给 \(x\),\(y\)。从两点出发,使得经过的点的数量等于 \(z\)。求经过的边最大编号最小是多少。
看到最大值最小。考虑二分。若只有一个询问。我们可以将边权小于等于 \(mid\) 的边领出来。然后用并查集合并。最后看 \(x\),\(y\) 是否在同一个连通块内。不在的话使得 \(siz_{get(x)} + siz_{get(y)} \ge z\),否则 \(siz_{get(x)} \ge z\) 就返回 \(1\)。
多个询问。整体二分即可。
[NOIP2012 提高组] 疫情控制
题目大意:给一棵有 \(n\) 个点,以 \(1\) 为根的树。有 \(m\) 个军队。先给出军队的位置。可以移动军队,每过一条边花 \(w_i\) 的时间。移动完毕军队所在的点不能走。军队最后不能在根。求使得 \(1\) 不与任何叶子联通花费的最小时间。
二分答案。
二分给定一个时间限制 \(lim\)。考虑如何写 check
。贪心的,除根以外,其他点均不会往下走。因为向上走(除走到根)一定能覆盖更多的叶子。
那么,我们将所有军队尽量向上移动,到根的儿子为止。可以用倍增实现。若到了根的儿子,求出剩余时间 \(more_i = lim - cnt - w_{1->i}\)。若有剩余时间,将这个结点(移动后)和 \(more_i\) 存下来。否则打上标记。
然后,我们 dfs 即可求出哪些以根的儿子为根的子树需要从其他子树要来军队。
但是,我们注意到,有剩余时间的我们并没有打上标记。所以我们需要求出那些点留在子树内即可。
先给出结论:\(more_i < w_{1->i}\) 的且这个子树的叶子没完全覆盖,这样的不用动这个点,同时,这个子树就被这个点覆盖。
感性证明:有一个满足上述条件的点 \(x\),和一个可以移动的点 \(y\) 且满足 \(more_y \ge w_{1->i}\),那么 \(x\) 之后可以移动到的点 \(y\) 一定能到,\(y\) 能到的,\(x\) 不一定能到。那么就别浪费 \(y\) 去 \(x\),\(x\) 去其他点。
但是根据上面结论,\(more_x\) 一定比其他在同一个点的 \(more_x\) 小才行,所以要排序。
最后使用双指针判断即可。