MX-2025 盖世计划 C 班 Day 2 复盘
今天是模拟赛
T1 (Count)
题目描述
给定 \(x,p\),求有多少个 \(y\) 满足 \(\gcd(x,y)^p=\operatorname{lcm}(x,y)\),答案对 \(998244353\) 取模。
数据满足 \(1\le x\le 10^9,1\le p\le 10\)。
思路
考虑 \(x=a^b\),其中 \(a\) 为质数。容易发现,如果 \(b\mod p=0\),\(y\) 可以取 \(a^\frac{b}{p}\) 和 \(a^{bp}\),否则只能取 \(a^{bp}\)。
对于一般情况,对 \(x,y\) 做质因数分解得 \(p_1^{c_1}p_2^{c_2}\dots p_k^{c_k}\)。分开考虑所有质因数,条件等价于 \(p\times\min\{c_{x,i},c_{y,i}\}=\max\{c_{x,i},c_{y,i}\}\)。在这个质因数上,\(y\) 有两种取法当且仅当 \(c_{x,i}\bmod p=0\)。答案为所有质因数分开计算取法后的乘积。
注意特判 \(p=1\) 的情况。
Time: \(\mathrm{O}(\sqrt{x})\)。
Code
T2 (seq)
题目描述
给定一个长度为 \(n\) 的的序列 \(a\)。从中选择 \(m\) 个数,将选择的元素按原顺序排成一个首尾相邻的序列 \(b\),此时,我们定义 \(b\) 的权值为所有相邻两个数之和的最大值(形式
化地,权值为 \(\max_{i=1}^m\{b_i+b_{(i\bmod m)+1}\}\)。求出 b 的权值最小能为多少。
数据满足 \(2\le m\le n\le 2\times 10^5,0\le a_i\le 10^8\)。
思路
考虑原序列中相邻和最大的一对数,我们删去其中较大的那个数。这样一定是不劣的,因为只有操作这一对才会让答案变小,删去较大的数也显然是最优的。不断重复该过程即可,可以使用链表和堆进行维护。
Time: \(\mathrm{O}(n\log n)\)。
Code
T3 (divide)
题目描述
给定一个长为 \(n\) 的序列 \(a\),将其划分为若干连续的段,如果每一段对应的数的 \(\operatorname{mex}\) 相等,我们称这种划分是好的。请你求出有多少种划分方案是好的,对 \(998244353\) 取模。
思路
记 \(\operatorname{mex}(l,r)\) 表示序列中第 \(l\) 个数到第 \(r\) 个数的 \(\operatorname{mex}\)。假设所有段的 \(\operatorname{mex}\) 都等于 \(v\),说明所有段都不含有 \(v\),进而说明整个序列不含 \(v\),于是 \(v\) 就一定是整个序列的 \(\operatorname{mex}\)。于是有 DP 方程:\(f(i)=\sum_{\operatorname{mex}(j,i)=v}f(j-1)\)。
根据 \(\operatorname{mex}\) 的性质,满足 \(\operatorname{mex}(j,i)=v\) 的所有 \(j\) 是一段前缀。维护每种数在 \(i\) 之前的第一次出现的位置,其中的最小值以及之前的都满足 \(\operatorname{mex}(j,i)=v\)。可以用 std::set 来维护这些位置,之后使用前缀和优化 DP 即可。当然,这些位置具有单调性,可以用一个指针维护。
Time: \(\mathrm{O}(n)\)。
Code
T4 (op)
题目描述
给定一个整数 \(p\) 和 \(n\) 个操作,操作分为以下两种:
- 给定 \(x\),将 \(w\) 修改为 \(x\);
- 给定 \(x\),将 \(w\) 修改为 \((w+x)\mod p\)。
其中 \(w\) 为一个初始为 \(0\) 的变量。
你可以以任意顺序执行上述 \(n\) 个操作,得到最终的 \(w\)。你需要求出在 \(\left[0,p\right)\) 中,有多少个数是无论以什么顺序执行操作都无法得到的。
数据满足 \(1\le T\le 2,1\le n\le 10^6,2\le p\le 10^6,\sum n\le 1.1\times 10^6,op\in\{0,1\},0\le x_i<p\)。
思路
特判掉没有赋值操作的情况。
可以发现只有最后一次赋值操作以及之后的加法操作是有意义的,因此可以转化为任选一个赋值操作和若干个加法操作能拼出来的数,将赋值操作作为初始状态,对所有加法操作跑一遍背包 DP 就能求得可以凑出那些数了。可以利用std::bitset 来加速,时间复杂度 \(\mathrm{O}(\dfrac{np}{w})\)。
思考这样一个背包的实质:对于每个权值 \(v\),更新所有的 \(i\rightarrow (i+v)\bmod p\)。可以发现有效更新始终只有 \(\mathrm{O}(p)\) 次,尝试从此处切入。
尝试对于每个修改,分治出这样的更新。用一个类似线段树的结构,以及一个额外的树状数组维护出区间的 \(dp\) 哈希值。断环为链后,如果区间 \(\left[l,r\right]\) 与 \(\left[l+v,r+v\right]\) 不相同,则递归下去修改。
这样分析势能存在一个问题。对于 \(dp_i=1\),但 \(dp_{(i+v)\bmod p}=0\) 的情况,上述算法并不会更新,但却会递归下去。也就是说势能被利用,但未减少。
考虑本题特殊的性质:背包是在模意义下进行的。在模意义下,所有的 \(i\rightarrow (i+v)\bmod p\) 必定会形成一个环。环上所有的 \((1.0)\) 都会对应一个 \((0,1)\),因此势能是正确的。视 \(n,p\) 同阶,Time: \(\mathrm{O}(n\log^2 n)\)。

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号