2025/7/24 模拟赛小记
感觉这场 mx 的模拟赛质量很高啊,这下不得不写个小记了(
\(100+35+20+30=185\) 了,怎么这么垃圾。如此成绩,如何 NOIP。
还是没怎么深度思考,感觉不好做就不想了,怎么回事呢??
T1
给定一个只包含小写字母的长度为 \(n\) 的字符串 \(s\),可以选择其中一个子串将其删除,求所有可能得到的结果中,本质不同的字符串个数。\(1\leq n\leq 5\times 10^5\)。
小签到题。整体来看信息是 \(\mathcal{O}(n^2)\) 级别的,所以我们只能考虑反着做,也就是从 \(\dfrac{n(n+1)}{2}\) 中删去重复计算的部分。
得到相同的字符串显然要求删去的部分长度相同,考虑把这个删去的部分视作一个长度为 \(l\) 的滑动窗口。考察这个窗口向右滑动一个单位的过程:剩下的部分从 \(s_1\cdots s_{l-1}s_{l+len}\cdots s_n\) 变为 \(s_1\cdots s_{l}s_{l+len+1}\cdots s_n\),对比可得,滑动后剩余字符串不变等价于 \(s_l=s_{l+len}\)。同时我们观察到,若滑动一个单位后剩余的字符串 \(s\) 变化为 \(s'\),那么 \(s\) 也不再可能和后面的字符串相同了。
因此我们只需计数有多少对 \((i,j)\) 满足 \(1\leq i<j\leq n\) 且 \(s_i=s_j\) 即可。这很唐了,开桶计数即可。时间复杂度 \(\mathcal{O}(n)\)。
T2
给定一个 \(n\) 个点 \(m\) 条边的无向简单图,要从 \(S\) 走到 \(T\),恰好经过 \(k\) 条边,且不能连续经过同一条边,求方案数。\(q\) 次询问 \(k\),答案对 \(998244353\) 取模。\(3\leq n\leq 200\),\(0\leq q\leq 100\),\(0\leq m\leq \frac{n(n-1)}{2}\),\(1\leq k\leq 10^9\)。
出题人是在怎样的精神状态下给出 \(q=0\) 这档部分分的??
出题人是在怎样的精神状态下要求选手卡常的??
\(k\) 的范围一眼引导我们推矩阵。但我赛时没推出来。。
令 \(f_{t,i,j}\) 表示恰好经过了 \(t\) 条边,从 \(S\) 走到 \(j\),最后经过的边为 \(i\rightarrow j\) 的合法方案数。不难得到转移:
这个形式根本做不了矩阵加速,考虑能不能把 \(i\) 去掉,也就是我们尝试求出 \(g_{t,j}\) 表示恰好经过了 \(t\) 条边,从 \(S\) 走到 \(j\) 的合法方案数。我们容斥,从 \(\sum_{i\rightarrow j}g_{t-1,i}\) 中减去连续经过一条边的方案数,那么经过 \(t-2\) 条边后的终点应为 \(j\),那就是计数形如 \(\cdots\rightarrow x\rightarrow j\rightarrow i\rightarrow j\) 的路径数,其中 \(x\neq i\),这其实就是 \(g_{t-2,j}(deg_j-1)\),因为对于每个 \(x\),\(i\) 都会对应 \(deg_j-1\) 种填法。因此
这样我们就可以构造出 \(2n\times 2n\) 的转移矩阵了,\(k\leq 2\) 要特殊处理,直接做是 \(\mathcal{O}(qn^3\log{k})\) 的。每次询问,我们给初始行向量右乘上 \(T^{k-2}\) 来获得答案,这里有一个板 trick:预处理 \(T^{2^0},T^{2^1},T^{2^2},\cdots\),询问时对 \(k-2\) 做二进制分解,每次给行向量右乘一个矩阵,这样乘一次的复杂度是 \(\mathcal{O}(n^2)\) 的,这样就可以做到 \(\mathcal{O}(n^3\log{k})\) 预处理,单次 \(\mathcal{O}(n^2\log{k})\) 地回答询问了。时间复杂度 \(\mathcal{O}((n+q)n^2\log{k})\)。
傻逼出题人要卡常,写个 \(8\) 位循环展开就过了。
T3
给定 \(n\),你要将 \(1,2,\cdots,2n\) 平分成两组。给定 \(m\) 条限制 \((a_i,b_i)\),表示要求 \(a_i,b_i\) 不在同一组,若第 \(i\) 条限制未被满足,则会产生 \(2^i\) 的代价。设 \(z_i=0/1\) 表示第 \(i\) 个人被分到了第 \(1/2\) 组,求最小代价,在此基础上最小化 \(z\) 的字典序。\(1\leq n\leq 5\times 10^3\),\(1\leq m\leq 10^6\)。
好题啊,这也太牛了。
经典的二次幂代价,当然考虑按限制编号从大到小贪心地考虑,尽量满足当前限制。考虑要满足什么条件才能把当前限制下的 \(a_i,b_i\) 分到不同组。一个显然的限制是用并查集维护二元关系,如果 \(a_i,b_i\) 连通,说明 \(a_i,b_i\) 已经被钦定分在同一组/不同组;否则说明我们可能可以将它们分到不同组。
连通性作为限制条件显然不够强,我们发现我们还要考虑将 \(a_i,b_i\) 分到不同组后能否平分。考虑当前的 \(k\) 个连通块,每个连通块 \((p_i,q_i)\) 告诉我们有 \(p_i\) 个数要分到同一组,\(q_i\) 个数要分到另一组,这个可以在并查集合并时轻松维护出来。那么问题转化为有 \(k\) 个二元组 \((p_i,q_i)\),从每个二元组中恰好取出一个数,问是否能使取出的数之和为 \(n\),这是简单背包,于是我们得到了 \(\mathcal{O}(n^2m)\) 的做法。实际上,更进一步地,我们只在 \(a_i,b_i\) 不连通时做背包,做完背包后连通块个数必然减少 \(1\),因此做背包的次数不超过 \(2n-1\),实际复杂度是 \(\mathcal{O}(n^3)\) 的。使用 bitset 可以进一步优化到 \(\mathcal{O}\left(\frac{n^3}{\omega}\right)\)。
考虑优化背包的部分。考察两个连通块 \((p_1,q_1),(p_2,q_2)\) 的合并,我们发现放到二元组上看,这等价于删去两个二元组,加入一个新二元组,变化量是极少的,那么每次都重新背包就显得很唐了。有删除操作,自然想到可撤销背包,我们判定转计数,每次判断是否有 \(f_n=0\) 即可。由于 \(f\) 的值会很大,我们需要在背包过程中模一个大约 \(10^{17}\) 级别的大质数 \(p\)。
具体解释一下可撤销背包的过程。首先考虑加入一个二元组 \((p,q)\) 时的转移式:
撤销二元组 \((p,q)\) 时,我们钦定 \(p<q\),按 \(j\) 从小到大转移。移项可得
需要注意的是我们要特判 \(p=q\),此时 \(f_{i-1,j-p}=\dfrac{1}{2}f_{i,j}\),乘上 \(2^{-1}\bmod{p}\) 时需要快速乘或者强转 __int128 再取模。
这样最小代价就做完了。对于字典序最小的部分,同样贪心,我们按编号从小到大考虑,尽量把当前数分到第 \(1\) 组,同样用可撤销背包判断是否合法即可。
时间复杂度 \(\mathcal{O}(n^2+m\log{n})/\mathcal{O}(n^2+m\alpha(n))\)。
T4
给定一个 \(n\) 个点的树 \(T\)。有 \(q\) 次询问,每次询问给定 \(x,y,k\),建一个无向图 \(G\),\(G\) 上 \(u,v\) 之间有边当且仅当在 \(T\) 上 \(\operatorname{dist}(u,v)\geq k\),求 \(G\) 中 \(x,y\) 的最短路,或报告无法到达。\(1\leq n,q\leq 10^6\),\(1\leq k\leq n\)。
其实相比 T3 倒不是很难。
考虑 \(T\) 上的任意一条直径,设其两端分别为 \(l,r\)。
考察 \(x,y\) 何时不连通,我们指出,\(x,y\) 不连通的充要条件是 \(x\) 到 \(l,r\) 的距离均小于 \(k\),或者 \(y\) 到 \(l,r\) 的距离均小于 \(k\)。
证明:由直径的最优性,任意点 \(p\) 在树上的最远点必然是 \(l\) 或 \(r\),如果 \(x\) 到 \(l,r\) 的距离均小于 \(k\),则说明其在 \(G\) 中是一个孤点,\(y\) 同理。而若对于 \(x,y\) 均存在直径的端点使得它们间隔的距离 \(\geq k\),则不妨设 \(\operatorname{dist}(x,l)\geq k,\operatorname{dist}(y,r)\geq k\),则我们至少可以做到 \(x\rightarrow l\rightarrow r\rightarrow y\)。\(\Box\)
先把无解判掉。由上述证明过程我们同样可以得出,\(x,y\) 间最短路的距离不超过 \(3\)。
最短路距离为 \(1\) 当且仅当 \(\operatorname{dist}(x,y)\geq k\)。
考虑判定最短路距离是否为 \(2\),这等价于判断是否存在点 \(p\),使得 \(\min(\operatorname{dist}(x,p),\operatorname{dist}(y,p))\geq k\)。设点 \(x\) 在直径这条链的 \(b_x\) 节点对应的子树中,\(b_y\) 同理。设 \(b_x,b_y\) 之间这条链上的节点,和链上节点的子树构成点集 \(S\),不难发现,若我们选择 \(S\) 之外的点,必然不如选 \(l\) 或 \(r\) 更优。所以我们只用考虑 \(S\) 中的点。
设 \(dep_x\) 表示 \(x\) 到直径的距离,\(id_x\) 表示 \(x\) 在直径这条链上的编号,令 \(q=b_p,u=b_x,v=b_y\)。若我们选择 \(p\in S\),则
对于相同的 \(q\),我们必然选择其子树中离直径最远的点 \(z\)。设 \(h_x\) 表示 \(sub_x\) 中的点到直径距离的最大值,则上式可以进一步简化为
\(dep_x,dep_y,id_u,id_v\) 均为常量,那么我们必然可以找到一个分界点 \(w\),使得对于 \(id_u\leq id_q\leq id_w\) 的点 \(q\),都有 \(dep_x+id_q-id_u\leq dep_y+id_v-id_q\),对于 \(id_w<id_q\leq id_v\) 的点 \(q\),都有 \(dep_x+id_q-id_u> dep_y+id_v-id_q\)。解不等式即可得到 \(id_w=\left\lfloor\dfrac{dep_y-dep_x+id_u+id_v}{2}\right\rfloor\)。
我们取 \(id_u\leq id_q\leq id_w\) 的情况进行说明,此时我们要最大化 \(dep_x-id_u+id_q+h_q\),在直径这条链上对 \(id_q+h_q\) 做 RMQ 即可。另一侧同理,对 \(id_q-h_q\) 做 RMQ 即可。
对于其他情况,最短路距离显然为 \(3\)。
我使用了 DFS 序 \(\mathcal{O}(n\log{n})-\mathcal{O}(1)\) 求 LCA。整体时间复杂度为 \(\mathcal{O}(n\log{n})-\mathcal{O}(1)\)。
闲话
还是感到力不从心了,感觉自己实在是太菜,太渺小了……
加油就行了。

浙公网安备 33010602011771号