Codeforces Round #441 (Div. 1, by Moscow Team Olympiad) 题解
A - Classroom Watch
考虑给定值是 \(x+y\),原来的值为 \(x\),那么显然 \(y\) 在 \(100\) 之内。暴力枚举即可。
B - Sorting the Coins
考虑一个局面对应的答案,等价于最后一个 O
前面 X
的个数 \(+1\)。树状数组可以直接维护。对应最后一个 O
的位置维护可以 std::set
,也可以倒着做。做的时候因为读题 + 没想清楚浪费了很多时间。复杂度 \(O(n\log n)\),应该可以 \(O(n)\)。
C - National Property
对于一个 \(i\in[1, n)\),如果 \(s_{i}\) 不是 \(s_{i+1}\) 的前缀,那么必然存在一个 \(k\) 满足 \(s_{i,k}\ne s_{i+1,k}\) 并且第 \(k\) 位之前全部相等,或者说我们必须造出这样一个 \(k\)。
具体而言,如果 \(s_{i,k}\ne 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}\to s_{i+1,k}\),当 \(u\to v\) 的有向路径存在时,如果 \(u\) 被改了,那 \(v\) 也改。最后检查一边合不合法就行了。复杂度都是 \(O(n)\)。
D - High Cry
考虑对于每个 \(i\),计算以位置 \(i\) 作为最大值的所有包含 \(i\) 的区间中,不合法的个数。那么这个区间 \([l,r]\) 应满足:
- \(i\in [l,r], \max_{j=l}^r a_j=a_i\);
- \(\forall j\in [l,r], a_i \text{ or } a_j=a_i\)。
第一个显然,第二个也不难理解:不合法的必然是最大值等与区间或值。单调栈计算第一个限制的边界,开个 \(\log a\) 大小的桶计算第二个限制的边界。总复杂度 \(O(n\log a)\)。
E - Delivery Club
二分答案是显然的。思考对于一个答案 \(K\) 如何判定合法性。
考虑一个 dp:\(f_t(i,j)\) 表示送完包裹 \(t\),一个人在位置 \(i\),另一个在 \(j\) 是否可能。然后有一个非常简单的优化:必然有一个人在 \(x_t\) 处,这样可以省掉一个维度。
整个 dp 数组不难维护,线段树即可。写完才发现可以用 std::set
直接维护 dp 值为 \(1\) 的位置,更加方便,亏大了。复杂度 \(O(n\log n\log x)\)。
F - Royal Questions
没想到,但是想到了思维深度其实也不大。考虑一个很神奇的图论模型:对于一个 \((a,b,w)\) 的公主抽象成一条无向边,那么王子就是点。最后我们选 \(k\) 个点 \(k\) 条边,并且对应的图联通。不难发现这样最终可以匹配上。
发现上面的条件实际上就是基环树!那么套用 Kruskal 生成树算法,外加记录一个连通块中是否有环,合并时随便维护一下就行了。复杂度 \(O(n\log n)\)。
本文来自博客园,作者:-Wallace-,转载请注明原文链接:https://www.cnblogs.com/-Wallace-/p/sol-cf-441.html