[关闭]
@himnouth 2022-08-25T11:44:19.000000Z 字数 2005 阅读 344

题解

CWOJ contest 0625 题解

Problem A

注意到如果没有二操作,就是一个简单的dp。观察发现连续执行两次执行操作二一定不优。因为若连续执行两次操作二,之前至少有一次操作三。那么把这两个操作二删去,在之前的操作三前添加一个操作二,一定更优且结果不变,得证。

那么对于一个操作二,它之前就只可能是操作三。

那么设 为得到 的最小步数,转移为:


时间复杂度

Problem B

观察发现其实当 的时候,可行的左端点是 级别的,对于这些情况,我们可以直接暴力尺取法,注意判断一下边界,因为很容易乘爆。

对于 ,发现左端点其实是 的,多组询问无法接受,于是考虑长度,发现可行的长度是 的,可以枚举长度并二分左端点得到答案。这样的话,预处理前缀平方和的数组会超过 unsigned long long 的存储范围,你当然可以使用 __int128 ,但是有一种更加优美的做法,我们知道二者相减一定是在 unsigned long long范围内的,所以考虑直接让前缀和自然溢出,这样就相当于对 取模,如果减出来是负数,那么加上一个 就可以得到希望的答案。

对于 ,套用等差数列求和公式有 。我们对 进行分解质因数然后枚举其所有约数作为 并检查是否合法即可,注意约数个数是相当有限的,所以这样是没问题的。注意对 级别的数分解质因数的时间有点无法接受,所以考虑预处理出 以内的约 个质数,并只枚举质数分解。枚举约数可以直接

复杂度分析省略。

Problem C

我们考虑对进行操作后的序列,发现只需要满足 就可以了。

于是考虑所有可行的 值。不妨记其为 。考虑确定了 后如何计算答案,发现一定是把比它小的数调整到 ,把比 大的数调整到 ,其它数不用管。

考虑所有可行的 发现它一定是 ,假设不是这些值,不妨让把所有的 在数轴上画出来,考虑用一条长度为 的线段在数轴上移动,其左端点为我们选择的 ,如果没有在哪些点上,我们向左或向右移动到那些点之后一定会更优,因为这个过程中,我们的左右端点不会越过任何一个会对答案产生贡献的点,所以,如果左边需要调整的点多,就往左,否则往右。

考虑对所有的这些点离散化,枚举 ,然后用线段树维护区间的有贡献的点 () 和它们的坐标和。分别计算左边和右边的贡献就可以得到当前的最优答案,把所有答案取 就可以了。

时间复杂度

存在 做法,请自行思考。

Problem D

考虑暴力的dp,设 为第 天在 的概率,时间复杂度 ,可通过子任务2。

容易发现,上面的 天和第 天的转移是一样的,即第 天的转移只和 有关,所以每个周期的转移是相同的。于是我们可以把 天作为一个周期,若设 那么 天可以划分为 个周期和余下的天数。考虑如何快速计算 个周期从 出发到达每个点的方案数,对于一个周期预处理出 ,表示从 出发,经过一个周期到 的方案数。如果把 看成矩阵,那么 个周期的方案数就是 ,可用矩阵快速幂优化。对于余下的 天直接暴力转移。时间复杂度 ,可通过子任务3。

上面算法的复杂度瓶颈在于求 个周期的方案数。我们考虑 矩阵记录的信息是否都是必要的?能否简化?接下来是经典的矩阵乘法转卷积的过程。

我们再次观察 矩阵,发现若 ,则 ,说明其实方案数只和起点和终点的位置差有关,而和起点无关。

所以我们调整状态,设 表示走完 个周期后,终点的位置相对于起点的位置之差为 (顺时针方向)的方案数。对于一个周期,我们预处理出 ,这一部分时间复杂度 。那么容易得到


这是一个卷积的形式,而 个周期就恰好是 卷起来,可以用快速幂优化。因为(暴力)卷积的复杂度是 的,所以这一部分复杂度 。总时间复杂度

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注