A - Classroom Watch
考虑给定值是 (x+y),原来的值为 (x),那么显然 (y) 在 (100) 之内。暴力枚举即可。
B - Sorting the Coins
考虑一个局面对应的答案,等价于最后一个 O
前面 X
的个数 (+1)。树状数组可以直接维护。对应最后一个 O
的位置维护可以 std::set
,也可以倒着做。做的时候因为读题 + 没想清楚浪费了很多时间。复杂度 (O(nlog n)),应该可以 (O(n))。
C - National Property
对于一个 (iin[1, n)),如果 (s_{i}) 不是 (s_{i+1}) 的前缀,那么必然存在一个 (k) 满足 (s_{i,k} e s_{i+1,k}) 并且第 (k) 位之前全部相等,或者说我们必须造出这样一个 (k)。
具体而言,如果 (s_{i,k} e s_{i+1,k}),那么有:
- (s_{i,k}>s_{i+1,k}):这时需要靠改掉 (s_{i,k}) 扭转乾坤。
- (s_{i,k}<s_{i+1,k}):那么我们需要维持现状,如果说 (s_{i+1,k}) 被改了,那 (s_{i,k}) 也应该被改,保持原有的大小关系。然而做的时候被我漏了。
然而有一点瑕疵:倘若在 (s_{i,k}>s_{i+1,k}) 情况中不仅改了 (s_{i,k}) 还改了 (s_{i+1,k}),怎么办?有两种解决方案,第一种比较直接,套用 2-SAT 模型即可,“改”与“不改”分别作为 (0,1)。或者是采用第二种,相对简单,只要对第二种情况建图,(s_{i,k} o s_{i+1,k}),当 (u o v) 的有向路径存在时,如果 (u) 被改了,那 (v) 也改。最后检查一边合不合法就行了。复杂度都是 (O(n))。
D - High Cry
考虑对于每个 (i),计算以位置 (i) 作为最大值的所有包含 (i) 的区间中,不合法的个数。那么这个区间 ([l,r]) 应满足:
- (iin [l,r], max_{j=l}^r a_j=a_i);
- (forall jin [l,r], a_i ext{ or } a_j=a_i)。
第一个显然,第二个也不难理解:不合法的必然是最大值等与区间或值。单调栈计算第一个限制的边界,开个 (log a) 大小的桶计算第二个限制的边界。总复杂度 (O(nlog a))。
E - Delivery Club
二分答案是显然的。思考对于一个答案 (K) 如何判定合法性。
考虑一个 dp:(f_t(i,j)) 表示送完包裹 (t),一个人在位置 (i),另一个在 (j) 是否可能。然后有一个非常简单的优化:必然有一个人在 (x_t) 处,这样可以省掉一个维度。
整个 dp 数组不难维护,线段树即可。写完才发现可以用 std::set
直接维护 dp 值为 (1) 的位置,更加方便,亏大了。复杂度 (O(nlog nlog x))。
F - Royal Questions
没想到,但是想到了思维深度其实也不大。考虑一个很神奇的图论模型:对于一个 ((a,b,w)) 的公主抽象成一条无向边,那么王子就是点。最后我们选 (k) 个点 (k) 条边,并且对应的图联通。不难发现这样最终可以匹配上。
发现上面的条件实际上就是基环树!那么套用 Kruskal 生成树算法,外加记录一个连通块中是否有环,合并时随便维护一下就行了。复杂度 (O(nlog n))。