0%

AGC045 简要题解

A - Xor Battle

我们从后往前维护 \(0\) 的线性基,当遇到某一个属于 \(1\) 的数时,如果其不能被当前线性基内的数表示,则 \(1\) 必胜,反正是否异或这个数没有影响,如果扫完了都没有判断成功,则 \(0\) 必胜。

提交记录

B - 01 Unbalanced

\(0\) 看作 \(-1\),那么现在就是让这个序列的最大前缀和减去最小前缀和最小。

\(f(z)\) 表示保证最大前缀和不超过 \(z\),最小前缀和最大能为多少。考虑怎么求,我们先把所有的 ? 设为 \(-1\),然后再从前向后扫,如果当前是 ?,且将其设为 \(1\) 后不会使得最大前缀和超过 \(z\),那么就可以贪心地将其置为 \(1\),判断可以通过计算后缀最大前缀和来实现。

设把 ? 都设为 \(-1\) 时最大前缀和为 \(m\),看上去我们要对所有 \(z\geqslant m\) 都需要求出 \(z-f(z)\),但注意到一定有 \(z-f(z)\leqslant z+2-f(z+2)\)。因为如果令 \(z:=z+2\),根据我们的算法,至多额外有一个位置由 -1 变成了 1,所以 \(f(z+2)-f(z)\leqslant 2\),所以我们只需要求出 \(m-f(m)\)\(m+1-f(m+1)\) 取较小值。

提交记录

C - Range Set

详见这篇题解

D - Lamps and Buttons

考虑最优策略是什么:如果按了一个 \(p_i=i\) 的按钮,则直接失败;反之可以把 \(i\) 所在的环全部点亮,如果某次操作结束所有环都被点亮,则胜利。由于每一种排列出现概率都是相等的,所以前 \(k\) 个元素以什么顺序按胜负概率也是相等的,所以我们只需要按顺序按未确定的灯。

我们枚举 \(t(t\leqslant A)\)\([1,A]\) 中第一个自环的位置(如果 \([1,A]\) 中没有自环,认为 \(t=A+1\)) ,则获胜条件为:对任意 \(i\in[A+1,n]\),存在 \(x\in[1,t)\) 使得 \(i,x\) 在同一个环内。

为了保证 \(t\) 是第一个自环的位置,我们需要容斥(二项式反演)钦定 \(t\) 之前有多少自环,那么现在问题转化为:计算长度为 \(a+b+c\) 的排列数量,且对于 \(i\in[a+1,a+b]\),保证存在 \(x\in[1,a]\) 使得 \(i,x\) 在同一个环内。考虑一个一个插空,前 \(a\) 个任意;对 \(i\in[a+1,a+b]\),有 \(i-1\) 中方案插进去;最后 \(c\) 个也任意。化简可知答案为 \(\dfrac{a(a+b+c)!}{a+b}\)

提交记录

E - Fragile Balls

我们把每个球看作一条 \(A_i\) 连向 \(B_i\) 的有向边。

考虑 \(C_i=1\) 的情况什么时候有解,结论是当且仅当这个图存在一个连通块,使得它是(不是包含)一个长度大于等于 \(2\) 的环(这里连通块指弱联通)。必要性考虑这样的连通块一定一开始每个盒子都有一个球,没法动,而 \(C_i=1\),不能从其他位置借球过来;充分性考虑对某一个连通块缩强连通然后拓扑排序,每次找到拓扑序最小的强连通分量。由于每个点在这个强连通内部的出度和入度都不为 \(0\),只需找到某个与其它强连通分量相连的点,其一开始一定有 \(\geqslant 2\) 个球,先遍历这个强连通分量,然后再去放到新的强连通分量里,这样会使遍历到的强连通分量也至少有一个盒子至少有两个球。

然后我们考虑一般的情况,设 \(P=\sum [A_i\not=B_i]\)\(X\) 为长度大于等于 \(2\) 的环的连通块个数 ,\(Y\) 为我们“使用”的单独一个自环的连通块数目(“使用”指我们把它移走然后又移回来),\(Z\) 为不是环的连通块中使用的自环个数。则我们有以下结论:有解当且仅当 \(\sum(C_i-1)\)(不包含未使用的自环)大于等于 \(X+Y\),且如果 \(X+Y\geqslant 1\),则存在一个 \(i\),其不在是环的连通块中且 \(C_i\geqslant 2\)。这时答案为 \(P+X+2Y+Z\)。证明类似 \(C_i=1\) 时,仍旧可以构造出每一步都能继续走的方案,具体可以看官方题解。

所以我们只需要处理出单独的自环和在连通块中的自环(用并查集实现),然后贪心+双指针求解,复杂度 \(O(m\log m)\)

提交记录

F - Division into Multiples

先把 \(A,B,C\) 处理成两两互质的情况,具体做法是先让 \(A,B\) 除以 \(\gcd(A,B)\)\(C\) 除以 \(\gcd(A,B,C)\)。然后这时 \(\gcd(A,C),\gcd(B,C)\) 不一定为 \(1\),设 \(\gcd(A,C)=t\),由于现在 \(\gcd(A,B)=1\),那么好的组内的 \(B\) 球的个数一定是 \(t\) 的倍数,所以我们让 \(A,C,Y\) 都除以 \(t\),类似地再对 \(B,C,X\) 做一遍。

我们考虑计算出好的二元组 \((x,y)\) ,即 \(Ax+By\equiv 0\pmod C\)。注意到如果把二元组放到坐标系中,如果一个点左下方还有点,则其一定不优,所以我们只需要求出左下方没有点的二元组。

\(D=\dfrac{A}{B}\pmod C\),则二元组 \((x,y)\) 可以改写成 \((x,(C-(Dx\bmod C)+C)\bmod C)\),由于好的二元组随 \(x\) 增加 \(y\) 减小,所以我们要找到 \((x,Dx\bmod C)\) 都是前缀最大值的二元组。

我们考虑给定一个长为 \(C\) 高为 \(D\) 的循环网格,一开始在 \((0,D)\),移动向量为 \((1,1)\),则当每次纵坐标 \(=D\) 则把横坐标记录下来(包括一开始),如果当前横坐标是记录的最大值,则当前横坐标就是 \(Dx\)

注意到我们一开始会从 \((0,D)\) 逐渐走到 \((D,D)\),注意到如果我们以后再走到 \((0,0)\)\((D,D)\) 这个正方形内,碰触的上边界一定不是最大值,而继续走直到走出正方形相当于从左边界平移到了右边界,所以我们可以把这个正方形删掉。

注意到这样的话我们每次令当前长度对高度取模,这样会获得若干差相等的纵坐标,即一段等差数列,而根据欧几里得算法的复杂度分析,我们只会获得 \(O(\log C)\) 种等差数列,我们把每种等差数列的开头第一个点和元素个数都记下来。

考虑怎么计算答案,注意到把所有点按 \(x\)\(y\) 排序后一定有 \(x_i-x_{i-1}\leqslant x_{i+1}-x_i\)\(y_{i-1}-y_i\geqslant y_i-y_{i+1}\)(考虑算法流程,\(x\) 其实就是碰到上边界的次数)注意到所有点形成了凸包,移项并简单扩展可知选的点的排名的极差不会超过 \(1\)。所以最优答案一定在同一个等差数列内(认为凸包顶点上的点同时属于两个等差数列),我们对每一种等差数列二分最多放出多少个,最后对所有取 \(\max\) 即可,总复杂度 \(O(\log^2C)\)。具体怎么二分可以看代码。

提交记录