IOI2025集训队互测 W5
Day13(20241112)
获得成就:在集训队员中登顶。
T1 线段树与区间加
感觉题解做法很牛,所以我来写一下我的 \(O(n\log n+q\sqrt{n})\) 做法。
我们先考虑单独维护 \(laz\) 数组。
如果先不考虑 pushdown。发现我们对区间 \([l,r]\) 进行加法操作,就是找到所有 \([L_i,R_i]\subseteq[l,r]\) 且 \([L_{fa_i},R_{fa_i}]\subseteq[l,r]\) 的节点 \(laz\) 增加 \(k\)。发现这个限制太奇怪了,所以我们考虑对于所有 \([L_i,R_i]\subseteq[l,r]\) 的节点 \(laz\) 增加 \(k\)。那么一个节点实际上的 \(laz_i\) 就等于 \(laz_i-laz_{fa_i}\)。
那么对其求和就有 \(\sum vb_i(laz_i-laz_{fa_i})\),交换一下顺序就有 \(\sum laz_i(vb_i-vb_{ls}-vb_{rs})\)。发现这样 pushdown 只需要把那些要 pushdown 的节点的 \(laZ_i\) 变成 \(0\) 即可。
我们记 \(val_i=vb_i-vb_{ls}-vb_{rs}\),那么我们维护的操作有:
- 对于所有 \([L_i,R_i]\subseteq [l,r]\) 的节点 \(laz_i\) 加上 \(k\)。
- 对于所有 \([l,r] \subseteq[L_i,R_i]\) 且 \([L_i,R_i]\not\subseteq [l,r]\) 的节点的 \(laz_i\) 清空。
- 查询的 \(\sum val_ilaz_i\)
发现把所有的 \((L_i,R_i)\) 看成二维平面上的点,那么要做的操作就是矩形加和矩形推平,考虑使用 KDT,时间复杂度为 \(O(q\sqrt{n})\)。
现在再考虑吧 \(a\) 数组。
仍然沿用上面对于 \(laz\) 的修改,那么对于一个区间,如果这个区间的实际区间和为 \(sum_i\),那么有 \(a_i=sum_i-laz_{fa_i}*len_i\)。
那么维护 \(\sum va_ia_i\) 就是要维护 \(\sum va_isum_i-\sum laz_i(va_{ls}len_{ls}+va_{rs}len_{rs})\)。对于前者,每一次修改的贡献可以通过前缀和和差分实现;对于后者,只需要将 \(val_i\) 修改成 \(vb_i-vb_{ls}-vb_{rs}-va_{ls}len_{ls}-va_{rs}len_{rs}\) 即可。时间复杂度仍然是 \(O(n\log n+q\sqrt{n})\),感觉跑起来还挺快的。
T2 字符串
考虑 \(S[i,i+l-1]<S[i+l,i+2l-1]\) 意味着什么,发现在绝大多数情况下等价于 \(rk_i<rk_{i+l}\),其中 \(rk_i\) 表示 \(i\) 在后缀数组中的排名。
而 \(rk_i<rk_{i+l}\) 可以直接二维数点,使用树状数组可以做到 \(O((n+q)\log n)\)。
发现反例就是 \(S[i,i+l-1]=S[i+l,i+2l-1]\) 但 \(rk_i<rk_{i+l}\) 的情况。考虑如何处理 \(S[i,i+l-1]=S[i+l,i+2l-1]\)。
直接使用优秀的拆分的 trick,先枚举 \(l\),然后找到满足 \(S[i,i+l-1]=S[i+l,i+2l-1]\) 的 \(i\) 连续段 \([L,R]\),那么如果有 \(rk_L<rk_{L+l}\),那么这一段区间都是被额外统计的。而这样的连续段最多只有 \(O(n\log n)\) 段,仍然使用树状数组进行二维数点可以做到 \(O((n+q)\log^2n)\),常数较小可以通过。
发现这种结构其实就是 runs,所以我们对于每一个 runs,枚举最小循环节重复多少次,这样得到的连续段 \([L,R]\) 只有 \(O(n)\) 个,时间复杂度也就做到了 \(O(n\log n)\)。
T3 格雷码
据说可以把这个题的大致做法。
发现格雷码的限制比较宽松,所以认为在 \(n\mid 2^n\) 时,极差为 \(0\);\(n\not\mid 2^n\) 时,极差为 \(2\)。
你发现直接构造是不太可能的,所以考虑增量构造。发现 \(n\to n+1\) 不太现实,所以考虑 \(n\to n+2\)。
在 \(n+2\) 中,我们对于后 \(n\) 位的构造还是依赖 \(n\) 的结果,想办法对于前两位来进行构造。
我们将 \(n\) 的序列拆成:\(A_1P_2A_2P_2\dots A_mP_m\),其中 \(A_i\) 是一段操作,\(P_i\) 是单个操作,\(A_i^R\) 记为 \(A_i\) 反转后的结果。
题解给出如下构造方式(\(m\) 为奇数):
发现 \(A\) 中的数出现了 \(4\) 次,\(P\) 出现了 \(2\) 次,但 \(P_m\) 没有出现,\(n\) 和 \(n+1\) 出现了 \(m+1\) 次。由于极差取的是最小值,所以数字出现次数的集合是确定的,想办法找到一组满足条件的分割即可。
Day14(20241115)
你说得对,但是 225,220,220,220,220...
T1 Two permutations
感觉这道题就随机写一写就写出来了?
显然有 \(i\) 不会在计算 \(i\) 的集合中出现,所以显然有 \(v_i\le i\),我们大胆猜测满足这个条件就一定有解。我们让 \(i\) 连向 \(v_i\),就会形成一棵树。
树的特殊情况是链,那么我们考虑 \(v_1=1,v_i=i-1(i\ge 2)\) 的情况。
通过暴搜发现只有四组解,他们本质上就是如下的结构:\(1325476\dots + 21436587\dots\)。
那么发现对于树上的每一条链,单独拉出来都是这个结构,那么我们按照从小到大加入每一个 \(i\),根据 \(v_i\) 所在的位置以及当前深度的奇偶性来决定会插入到那一个位置:例如对于左侧,深度为奇数的点会插在最后面,深度为偶数的点会插在 \(v_i\) 的后面。发现可以使用链表维护,时间复杂度 \(O(Tn)\)。
T2 冲刺
这种题的受众到底都是谁
T3 串联
考虑使用合并果子点分治。我们就考虑经过分治中心的所有路径。我们看每一个点到分治中心的路径,我们关注他的路径上最小值 \(A_i\) 和权值和 \(B_i\)。那么我们想要找到异侧的两个点 \((i,j)\),使得其满足 \(\min(A_i,A_j)(B_i+B_j)\ge V\) 的最小的 \(B_i+B_j\)。
考虑按照 \(A\) 从大到小枚举 \(i\),找到所有 \(A_j\ge A_i\) 中 \(B_j\ge \dfrac{V}{A_i}-B_i\) 的最小的 \(B_j\),可以直接使用数据结构维护。
时间复杂度 \(O(n\log^2n)\)。
Day15(20241117)
今天集训队 rk1 和 rk15 分差 \(300\),感觉自己错完了。
T1 药水
记 \(D=r-l+1\)
发现清空这个问题是不好处理的,所以我们尝试将问题倒序过来:
实时维护一个数 \(x\),表示当前还需要多少药水。如果某一天 \(i<0\),那么令 \(x\gets x-i\),表示需要的药水数增加了 \(|i|\);如果 \(i\ge 0\),那么令 \(x\gets \max(0,x-i)\),表示有了 \(i\) 瓶药水。同时,每一次操作之后要保证 \(x\le k\),同时连续的 \(m\) 天中至少有一个 \(x=0\)。
发现 \(x=0\) 之后前后的状态是相对无关的,我们只关注 \(x\) 从 \(0\) 开始,进行一定数量的操作之后,第一次到 \(x=0\) 这一段。假设长度为 \(len\) 的概率为 \(f_{len}\),那么我们只关注 \(1\le len\le m\) 的情况,记 \(F=\sum\limits_{i=1}^mf_ix^i\),那么最终的答案就是 \([x^n]\dfrac{1}{1-F}\)。
由于只找第一次 \(x=0\) 的时刻,所以可以认为是找第一次 \(x\le 0\) 的情况,那么就可以把二操作的取 \(\max\) 去掉。
考虑如何刻画 \(x\le k\) 和 \(x>0\) 的限制。发现在 \(l=-1,r=1\) 的时候长得很像格路计数,所以尝试使用各路计数去考虑,那么每一次就是向右走 \(1\) 步,向上走 \(x\in[l,r]\) 步。
我们可以在所有 \((i,j)\) 处放上障碍,其中 \(i\in \{-2,-1,0,k+1,k+2,k+3\},j\in \{1,2,\dots m\}\),我们就是要对于每一个障碍 \(p\),统计它是第一次被遇到的概率 \(W_p\)。
记 \(W(p)\) 表示从 \((0,0)\) 走到 \(p\) 的概率,记 \(G=\sum\limits_{i=l}^ra_ix^i\),那么 \(W(p)=[x^{p_y}]G^{p_x}\)。
那么 \(f_p=W(p)-\sum\limits_{q}f_qW(p-q)\),发现这个转移时单向的,所以可以使用分治 NTT 来时限。那么现在的问题就是求出所有的 \(W(p)\) 和 \(W(p-q)\)。
发现所有需要的 \(W(p)\) 中 \(p_x\) 取遍了 \(1\sim m\),但是 \(p_y\) 只有 \([k+1,k+D]\),\([-D,D]\),\([-k-D,-k-1]\) 这共计 \(O(D)\) 个数。
同时由于 \(G\) 的项数也只有 \(D\) 项,所以可以通过分析 \(tG'(G^t)=G(G^t)'\) 的某一项系数,发现可以从 \(G^t\) 连续的 \(D\) 项系数得到他的上一项或者下一项,同时我们也可以从 \(G^t\) 的连续 \(D\) 项得到 \(G^{t+1}\) 的某一项。那么所有我们需要的 \(W\) 都可以递推出来。
复杂度疑似是 \(O(mD\log m(D+\log m))\),但是我没写代码,我不知道。
T2 字符游戏
没搞懂,不会细节。
博弈论问题,所以我们考虑计算 SG 值。发现每一步只会有 \(|\Sigma|\) 中决策。
发现通过维护一些东西之后,是可以支持对一个字符串 \(O(|\Sigma|^2)\) 地从前面或者后面插入一个字符,\(O(|\Sigma|^3)\) 地合并两个串。
所以直接套用点分树,可以做到 \(O(n\log n|\Sigma|^2+q|\Sigma|^3)\) 的复杂度。
T3 子集和
发现这个循环卷积无法加速,所以对于单次询问,我们仅能支持 \(O(m)\),那么发现 \(O(m)\) 能够支持对于两个多项式查询某一个点的值,所以我们想办法把问题变成两个多项式的乘积。
首先将 \([l1,r1]\times [l2,r2]\) 的询问差分成 \([1,L]\times [R,n]\) 的。
考虑猫树,我们找到 \(l\le L\le mid<R\le r\) 的节点,那么我们应当在这个节点维护如下信息:对于所有 \(l\le i\le mid\),维护 \(\sum\limits_{j=1}^i f(\{1,2\dots mid\}\setminus \{j\})\);对于每一个 \(mid<i\le r\),维护 \(\sum\limits_{j=i}^nf(\{mid+1,mid+2\dots n-1,n\}\setminus\{j\})\)。那么从查询可以直接合并 \(L\) 和 \(R\) 处对应的信息。
那么考虑如何构造,我们只考虑左侧,右侧是对称的。对于 \(\sum\limits_{j=1}^{l-1} f(\{1,2\dots mid\}\setminus \{j\})\) 是可以从父亲处继承过来的,而 \(\sum\limits_{j=l}^i f(\{1,2\dots mid\}\setminus \{j\})\) 的部分,我们可以再用一次分治乘的方式 \(O(mlen\log(len))\) 的求出所有的 \(f(\{1,2\dots mid\}\setminus \{j\})\),然后做一遍前缀和即可。
时间复杂度 \(O(nm\log^2n+q(m+\log n))\)。

浙公网安备 33010602011771号