官方英文题解
A. Bitwise #
从高位往低位贪心,写一个函数判断能否至少得到x
。
如何判断能否至少得到x
?依然是贪心的思路,我们从某一位开始,记录当前的或值,如果大于x
就开始新的一块。但如果从每个数都开始试一遍的话时间复杂度是O(n2)。但是我们发现每个块的结束位置一定是某一位变成 1 的位置,所以说开始的位置其实并不重要,最多只会少算一个部分,所以如果我们遍历两圈,如果至少有2k−1个块的话就说明x
是可行的。
B. Conveyor Belts #
我们可以把一个点拆成K个点,第i个点代表第tmodK时刻。原图中a -> b
的边拆完之后就变成了a
的第i时刻连到b
的第(i+1)modK时刻,容量为 1。这样就保证了每时刻每条传送带上只有一个物品。然后添加一个超级源点,连到第i个 producer 的第i时刻,容量为 1。最后从第N个点的每一个时刻连到一个超级汇点,容量为无穷大。然后跑个最大流就行了。
C. Free Food #
暴力标记每一天即可
D. Hoppers #
如果有长度为奇数的环的话并且整个网络连通就能传播到整个网络。所以只少检查每个连通分量是不是二分图并计算连通分量的个数就行了。
队友写的所以没有代码 QAQ
E. Largest Triangle #
这题过于经典,网上应该有很多题解。
G. Non-Prime Factors #
先预处理答案,类似筛法的思路:如果不是质数就把它的倍数们的答案加 1,质数就把它的倍数们标记成合数。O(1)输出询问即可。快读貌似不是很有必要。
J. SG Coin #
其实就是个取模下的减法。。。
L. Wi Know #
首先我们观察到:对于i<j<k,Si=Sj=Sk,(Si,Sk)一定不差于(Sj,Sk)。所以在A,B,A,B 中第一个 A 我们一定选在S中第一次出现的 A。同理,第二个 B 一定选S中最后一出现的 B。
解法的大致思路就是固定 B 找最小的 A。一种比较 naive 的思路是在[i+1,lasti−1]中查询最小值,但有两个问题:
- 不知道最小值在i之前有没有出现过。
- 最小值可能等于Si。
所以我们不能一次把所有的数都放到线段树里,要按一定的顺序放。对于每个位置i,我们记录一个nxti为Si的下一个出现位置。然后我们遍历S,首先查询[i+1,lasti−1]中的最小值 min,然后用{min, S[i]}
更新答案,最后在线段树中把nexti设为Si。
这样为什么避免了上面的两个问题呢?首先,只有在i之前出现过的数才会被加进去,避免了问题 1,然后我们是先查询再添加,而且一次只加一个,这样就避免问题 2。总之这个解法还是很妙的,比官方题解简单不少。