加载中...

牛客小白月赛110(EF)

E

比较有意思的思维题

按下标可以分为若干个组,先对每组内升序排序,再按值排序,一定是最优的。目前还不太会证明,以后有机会再补充证明,具体细节见代码。

code

F

双指针 + 模运算式推导

首先特判掉 \(x=0\) 的情况,因为只有不含0的数组才符合要求,所以只需要将所有 \(a[i]=0\) 改为非0值即可。

若区间 \([l,r]\) 不满足约束条件,即:

\[\frac {mul_{r}}{mul_{l-1}} mod p = x \]

考虑将式子变换成:

\[mul_{r} = (x + k*p)*mul_{l-1} (k \in Z) \]

\[\frac {mul_{r}}{x + k*p} = mul_{l-1} \]

\[mul_{r} * inv(x + k*p) = mul_{l-1} \]

其中

\[inv(x + k*p) = qpow(x + k*p, p-2,p) = (x+k*p)^{p-2} mod p = x^{p-2} mod p = inv(x)\]

因此:

\[mul_{r} * inv(x) = mul_{l-1} \]

\(x\) 是固定的,对于任意固定右端点 \(r\) 的区间,只需要看其前缀是否有满足上式的左端点即可。

\(x \not= 0\) 时,对于任意包含0的子区间均满足条件。因此对于不合法区间,只需要将某个元素修改为0即可。

用双指针 \(l,r\) 来遍历,每次看右端点为 \(r\) 的所有子区间 \([l,r]\)是否均满足要求(\(l\) 范围在 \(r\) 之前的第一个 \(a[i]=0\) 的后一个位置),若存在不满足要求的左端点,则贪心地将最右侧端点 \(a[r]\) 赋为0即可(容易证明这样一定最优,因为保证了前面的同时,后面的区间范围更小了),并将 \(l\) 的范围更新成 \(>=r+1\)。具体细节见代码。

code

posted @ 2025-02-15 09:58  jxs123  阅读(19)  评论(0)    收藏  举报