2024.10.[11, 13]训练记录
10.11 补题专题
补了9号的题。
晚上旷竞赛课(请假了)去排运动会开幕式,在学校操场大声唱了海阔天空/oh。
合唱团佬说我可能只低了2~3个音,赢。
嗓子哑了,输。
10.12
上午 noip模拟
A
是一个前缀和预处理的计数。场切了。hloj上过了。
但是最后在联合评测的评测机上MLE了,最后发现有个挺大的数组开了没用。/fn。
B
题意容易转化成 \(\Sigma (C(i, j) \bmod 2) * sum(i, j)\)。
\(1 \leq i, j \leq 10^5\) 的情况下 \(C(i, j)\) 是奇数的情况大概有 \(2*10^8\) 种。
也就是说,如果只遍历到 \(C\) 是奇数的点,常数小一点就是能过的。
这里考场出现了失误,感觉奇数点的个数大约是 \(10^8\),但是不知道为什么没有考虑到能过。
应该 \(n^2\) 跑一遍 \(10^5\) 的情况看看具体个数的,因为最终还是没有相信自己的估算。
所以 \(n^2\) 暴力打了很奇怪的方法,大概是把组合数写乘阶乘的形式,算一下阶乘里有几个 \(2\) 就可以判组合数奇偶性。
看看远方的正解吧:
法1:
把 \(C\) 的奇偶性打出来可以发现这玩意的图形是个分形。
应该模一下循环节就可以判断当前点在最小分形里的位置,于是可以直接跳到下一个 \(1\) 的点。
据 @hloixyh 说,这玩意有个板子叫南蛮图腾,这题有印象但是自始自终没打过。
但其实感觉跟那个没啥关系/youl。
法2:超绝数学。
有一个很厉害的东西叫卢卡斯定理。
\(C(n, m) \equiv C(\lfloor \dfrac {n}{k} \rfloor, \lfloor \dfrac {m}{k} \rfloor) * C(n \bmod k, m \bmod k) \pmod k\)
这个式子比较好背,比较难应用/yiw?至少应用到这题我只会 \(O(1)\) 判组合数奇偶性,那2的个数也能做。
厉害在这玩意有个引理。\(C(n, m)\) 是奇数当且仅当二进制下m是n的子集。
于是我们用那个复杂度是二项式定理的写法枚举子集,就能做到只遍历1。
数学好的选手都切掉了,但是我想了2h+还只会 \(n^2\) /kk。
反思一下。
卢卡斯定理这个式子其实一直都知道,说这个名字我能想起来这个式子。
引理因为不知道证明方式就忘了。现在要去看一下证明,避免之后忘。
印象里不久前的一场模拟赛是考到了的。那题是订正过的。这下俯卧撑了。
还有就是,遇到复杂度不明,疑似能过的,不要吝啬几分钟的时间,去验证一下实际的复杂度。
这个问题影响到策略,我觉得很重要。
C
40pts暴力,60pts暴力+线段树。于是考场拿了60。
这题涉及了一些考前不会的知识点(凸包)。订正完了。
先记一下求凸包的方法:
定义 from OI-wiki :在平面上能包含所有给定点的最小凸多边形叫做凸包。
只维护下凸壳的话,凸壳上每一个点到上一个的斜率是递增的。于是把每个点按x排序,按斜率做单调栈。
具体是当 \(\lfloor\) 栈中前两个点的斜率 \(>\) 栈中上上个点和当前点的斜率 \(\rceil\) 时,把栈顶弹掉(while
)。
每次把当前点入栈。
设 \(d\) 为原题中 \(d\) 的前缀和,\(m\) 仍是原题中的 \(m\)。
需要对于每个参数维护序列中 \((ax + y)\) 的最值时,可以使用凸包上二分。
把每个 \((x, y)\) 看成平面直角坐标系上的点,维护一个凸包。
然后在上/下凸壳上二分找到一个对于斜率为 \(-a\) 的直线的最低的切点。
具体上还是下看 \(a\) 的正负,这题 \(a\) 是正的,于是在下凸壳上二分。
设这个切点为 \((x1, y1)\),那么这条切线的方程就是 \(ax + y = ax1 + y1\),即纵截距是 \(ax1 + y1\);
因为是最低的切点,所以这条直线与 \(y\) 轴的交点就是这个凸包里最低的,这个纵截距就是最值。
注意,斜率为 \(k\) 的直线能和下凸壳中一点切需满足这一点和前一个点的斜率小于等于 \(k\),和后一个点的斜率大于等于 \(k\)。
而下凸壳中斜率是单调递增的,所以能在下凸壳上二分找出这个切点。
这是对于每个不一样的 \(V\),求 \(min(d_i + V * m_i)\) 的过程。对于静态问题就能这么做。
但是这题带修,于是可以将原序列分块。对于每块单独求凸包做最值。
具体来说,修改 \(d[p]\) 时,因为 \(d\) 是前缀和,所以需要后缀修改:
在 \(p\) 这一块中,将 \([p, R[p]]\) 的值直接暴力修改,\(p\) 这一块重求一次凸包。对于 \(p\) 后面的块可以打一个 lazytag,统计答案的时候加上即可。
修改 \(m[p]\) 时,只需要将 \(p\) 这一个点的值修改,再在 \(p\) 这一块重求一次凸包。
可以发现最多只需要对 \(p\) 这一块重求凸包以及遍历后面的块。所以修改复杂度是 \(O(\sqrt{n})\)。
就做完了,因为做凸包要排序,所以复杂度是 \(O(Q \sqrt{n} \log{sqrt{n}})\)。(大概/yiw)。
实际证明T了,块长换成 \(\dfrac {sqrt{n}}{2}\) 会更快,过了。
第一次写凸包,10.13早上才过。
10.13
下午 ARC174短时模拟赛
AB
会做,好做。按下不表。
C
输。
设a_i, b_i表示已经填了i个数的期望代价。
有: