AtCoder Beginner Contest 347

AT link

Problem A and B

略。

Problem C

按照模 \(a + b\) 分类,记录最大值和最小值,如果差值小于等于假期时间即可,否则还需要判断按照 \(d_i = D_i \bmod (a + b)\) 排序后相邻的两个是否满足条件。

Problem D

分离出 \(C\) 的二进制位,然后对于每一位 \(c_i > 0\) 尝试在 \(A, B\) 中找一个 \(1\) 放进去,实际上应该放数量更多的那个,放不下则无解。

然后此时 \(A, B\) 中多出来的 \(1\) 应该自己抵消,所以判断数字不相等就无解。最后在每个 \(c_i = 0\) 的位置放上两个 \(1\),最后如果多了就抵消。

Problem E

首先我们可以轻松得到每次操作后集合的大小,将其前缀和 数组记为 \(s_i\)。

那么我们考虑一个位置上的数字什么时候会产生贡献,显然是只有出现奇数次的时候,会有连续的一段贡献,那么记录上一个出现的位置,扫一遍就行,最后统计到序列结束仍只有一次的个数。

Problem F

原题。

Problem G

网络流,但是模拟退火。

注意将空的位置初始化为 \(1\),不要调整法,直接随机一个数字赋值就能过。