ZROI 19.08.05模拟赛

传送门

写在前面:为了保护正睿题目版权,这里不放题面,只写题解。


  • A

(21pts:)

随便枚举,随便爆搜就好了。

(65pts:)

比较显然的dp,设(f_{i,j,k})表示在子树(i)中,两个赞助商分别选了(j,k)个的最优解。

对枚举的上下界卡的紧一点,按照树上背包的聚合分析,复杂度是(O(n^3))的,可以通过。

(100pts:)

观察数据范围可以发现,这题的子树大小限制可以抽象成一个经典的网络流模型。

跑一个最大费用流就好了。

我写丑了,每个点拆了(5)个点出来,然而还是跑的飞快。


  • B

(22pts:)

枚举全排列/状压。

(100pts:)

这题非正解不太好写,直接上正解吧。

先考虑什么时候无解。随便弄一棵生成树出来,如果(sum a_i<sum w_i),显然无解。

现在我们要证明,只要(sum a_i geq sum w_i),一定有解。

考虑我们缩点缩到一个局面,此时所有边都无法缩起来。此时对于每条边((u_i,v_i,w_i)),都有(w_i>a_{u_i}+a_{v_i})

将所有不等式加起来,我们得到(sum w_i > sum a_icdot dgr_igeq sum a_i),显然与我们之前的假设矛盾。

所以,我们证明了对于一棵生成树,只要(sum a_i geq sum w_i),一定有解。那么显然取最小生成树最优。

那么我们考虑对一个满足(sum a_i geq sum w_i)的树,如何构造出一种方案。

首先设(s_i=a_i + sum_{jin subtree_i} a_j-w_{(j,fa_j)}),即(i)点子树中所有点权和与边权和之差。

对每个点(i),我们算出它的每个儿子(j)(s_j-w_{(j,i)}),设这个值为(v_j),按照(v_j)把它的儿子从大到小排序。((v_j)的实际意义在于,将子树(j)的所有点连接到父亲上之后,父亲点权的增量)

对于一个儿子(j),如果(s_jgeq 0),则先递归处理这个儿子,再连接它与父亲之间的边。

否则,这个儿子无法自己处理子树中的边,需要先连接父亲与它的边,再递归处理子树,并将父亲剩余的权值传递下去。

正确性存疑的地方只有连接某个儿子时,由于减去了某条边的权值,权值和可能(<0)

发现对于(v_igeq 0)的点,连接后一定会使父亲的剩余权值增大,不会影响。

否则,此后的点(v_i)均为负。由于最后父亲剩余权值(geq 0),则在这个不断减小的过程中也不会(<0)

实现时,发现一个儿子的影响只和(v_i)的正负性有关,因此并不需要排序,只需扫两遍,先取(v_igeq 0)的儿子,再取(v_i<0)的儿子即可。

复杂度(O(nlog n)),瓶颈在于求mst时的排序。


  • C

(6pts:)

显然质数的答案一定是(0)

(34pts:)

爆搜+打表,可以过掉(nleq 100)

(51pts:)

看到出题人完全平方,就很容易想到质因数异或线性基。

用bitset维护每个质数,复杂度(O(frac{n^4}{64ln ^2n})),实现优秀可过(nleq 1000)

(100pts:)

(g(x))(x)向左找到的最近的数,即与(f(x))意义类似,只是方向相反的函数。

发现(f(x))(g(x))互为反函数。

证明:假设从(f(x))向左找到的第一个位置为(y>x),则我们把两次找到的序列取对称差(即异或),则得到的新序列也是完全平方数,发现由于(f(x))在两个序列里都出现了,且(x)只出现了一次,所以可以找到一个左端点为(x),右端点(<f(x))的序列,与(f(x))是向右找到最近的数矛盾。

也就是说,每个合数都有且仅有一个互不相同的解,且答案为(g(x))

考虑从(x)往前扫,每次加入一个(l),看是否线性无关即可。复杂度(O(frac{n^3}{64ln ^2n})),好像没什么用。

发现超过(sqrt n)的质数只会有一个,在线性基上特判一下即可。

不超过(1000)的质数只有(168)个,复杂度(O(frac{168^2 imes n}{128})),由于对于实际上跑不满(比如答案不会超过(frac n2)),所以可过。

原文地址:https://www.cnblogs.com/suwakow/p/11375082.html