CSP2024-26
2A
题意:\(1\sim n\) 排在数轴上,定义 \(con_{i, j} =[i, j\text{ 直接或间接连通}]\),当前局面的代价为 \(\sum_{i < j} con_{i, j} \times a_{j - i}\)。
初始连满 \(\frac{n(n - 1)}{2}\) 条边,求恰好删去 \(0, 1, \cdots, \frac{n(n - 1)}{2}\) 条边后的最小代价。\(n \le 100, a_{i} \le a_{i + 1}\)。
在一个大小为 \(m\) 的连通块中,不管是 \(m - 1\) 条边还是 \(\frac{m(m - 1)}{2}\) 条边,其贡献都是一样的。
注意到 \(a\) 单调不降,连通块一定是一段连续区间,否则不优,调整法证明。
设前 \(f(i, k)\) 表示前 \(i\) 个点中恰好连了 \(k\) 条边的最小代价,\(f(i, k) \gets f(i - 1, k)\)。
考虑用 \(i\) 所在连通块转移,枚举左端点 \(j\),新增代价 \(w = \sum_{l} a_l \times (m - l)\),新增边数 \(d \in [m - 1, \frac{m(m - 1)}{2}]\)。
\(f(i, k) \gets w + \min f(j - 1, k - d)\),st 表预处理能做到 \(O(1)\) 转移。时间 \(O(n^4)\),空间 \(O(n^3\log n)\),不是很牛。
对于每个方案,我们都可以将其连通块中的边连满,但代价不变。
\(f^\prime(i, k)\) 表示前 \(i\) 个点恰好连 \(k\) 条边,且每个连通块边都连满的答案,\(f^\prime(i, k) \gets w + f^\prime(j - 1, k - \frac{m(m - 1)}{2})\)。
由于 \(f\) 是单调不降的,\(f(k)\) 的方案一定能对应到某个 \(f^\prime(l \ge k)\) 的方案,有 \(f(k) = \min_{l \ge k} f^\prime (l)\)。
1A
题意:\(n\) 个点 \(q\) 次操作,\(1 \le n, q \le 10^5\)。
- 连接 \(u, v\),数据保证无重边自环。
- 给定 \(k\),每次可以删掉度数不大于 \(k\) 的点,求可以删多少点(没有真删点,无后续影响)。
考虑最终局面的几种情况:
- 所有点都被删掉。
- 留下 \(r > k\) 个点,注意任意 \(i\) 满足 \(d_i >k\),即边数是 \(O(k^2)\) 的,\(k\) 是 \(O(\sqrt m)\) 的。
对于 \(k > O(\sqrt m)\),答案一定就是 \(n\)。
对于 \(k \le O(\sqrt m)\),考虑暴力怎么做:类似拓扑排序,不断删掉度数 \(\le k\) 的点并更新度数。
加边不好处理,删边好处理,把 \(k\) 相同的询问按时间轴从后往前一起处理,时间复杂度 \(O((n + q)\sqrt q)\)。
B
洛谷P7830,强制在线。
题意:给定一棵树,第 \(i\) 个点度数为 \(d_i\),依次与 \(v_{i, 0}, v_{i, 1}, \cdots, v_{i, d_{i} - 1}\) 相连。
每个点都有一个指针 \(c\),询问时会被初始化成 \(0\)。
在 \(i\) 点走一步定义为:\(c_i \to (c_{i} + 1) \bmod d_i\),\(i\) 走到 \(v_{i, c_i}\)。每次询问从 \(1\) 走 \(k\) 步会到哪个点。
数据范围:\(2 \le n , q\le 8 \times 10^5, 1 \le k \le 10^{15}\)。
如果所有指针一开始就指向其父亲,会出现什么情况?
访问到 \(u\) 之后会依次遍历 \(u\) 的儿子及其子树,最后 \(u\) 的指针指向父亲,回溯到父亲。
每条边都会遍历两次,得到一个长度为 \(2n - 2\),姑且称他为完全序的东西。
且由于指针最后全部归位,下次遍历还是完全一样的过程,即找到了一个周期。
考虑一般情况。
定义一轮遍历为从 \(1\) 开始,直到其指针恰好回到初始状态。
第一次遍历到 \(u\) 时,会递归遍历 \(fa_u\) 之前的儿子,然后指针指向父节点,往上回溯。
第二次遍历到 \(u\) 时,由于初始指向父节点,\(u\) 会遍历其所有儿子。
不难发现,第 \(i \ge n\) 轮一定就是完全序,只要考虑 \(i \le n\) 的情况。
设 \(t_u\) 表示 \((u, fa)\) 第一次被遍历到的轮数,如果 \(u\) 在父亲的父亲前面,\(t_u = t_{fa}\),否则 \(t_u = t_{fa} + 1\)。
通过 \(t_u\) 我们可以得到第 \(i\) 轮遍历得到的序列长度,具体来说,边 \((u, fa)\) 会对 \(t_u \sim n\) 轮的长度产生 \(2\) 的贡献。
第 \(i\) 轮遍历得到的序列中 \(u, v\) 两个点位置的偏序关系与最终完全序中这两个点的偏序关系相同。
这启发我们可以初始让整个完全序"未激活",当 \((u, fa)\) 被第一次访问到时"激活" \((u, fa)\) 对应的两个位置,主席树维护当前激活状态。
对于询问 \(k\),如果 \(k >\) 前 \(n\) 轮长度总和,那么已经陷入循环,减掉长度和后找模 \(2n - 2\) 的等价类即可。
否则二分找在哪一轮遍历中,主席树上二分找已经被激活的第 \(k\) 个位置。submission
C
CF1033F,加强了数据范围,2800 --> 3300+。
题意:给定长度为 \(n\) 的序列 \(a\),\(q\) 组询问。
每次给出字符串 \(s\) 和整数 \(z\),\(s\) 仅包含 \(A, O, X, a, o, x\),分别表示与、或、异或、与非、或非、同或。
查询有序对 \((i, j)\) 个数,满足 \(a_i \odot a_j(s) = z\)。
\(x\odot y (s)=z\) 表示任意 \(x_i\) 与 \(y_i\) 通过 \(s_i\) 得到的结果与 \(z_i\) 相同,\(x_i\) 表示 \(x\) 从高到低第 \(i\) 位。
数据范围:\(1 \le w \le 16, 1 \le n \le 10^5,\ 1 \le q \le 10^5,\ 0 \le a_i, z < 2^w,\ \vert s\vert = w,\ \sum = \{A, O, X, a, o, x\}\)。
任意 \(z \ne 0\) 都可以转化为 \(z = 0\)。
\(z_i = 1\) 等价于 \(\lnot z_i = 0\),进行 \(s_i\) 运算再取反,等价于进行和 \(s_i^\prime\) 的真值表完全相反的 \(s_i^\prime\) 运算,每组大小写字母都满足这个条件。
现在只讨论 \(z = 0\) 的情况。
观察真值表:
发现中间两行是完全相同的,这说明 \(z_i\) 的取值只与 \(x_i + y_i\) 有关。
把 \(a\) 看做每位只有 0/1 的三进制数,记 \([x^n]A(x) = \sum [a_i = n]\),\(A\) 做加法卷积(不进位),设 \(C = A^2\)。
每个 \(s_i\) 相当于限定了对应位上 \(a_{x, i} + a_{y, i}\) 的和:\(\texttt O,\texttt a, \texttt x\) 对应 \(0, 2, 1\);\(\texttt A,\texttt X,\texttt o\) 对应 \(0/1,\ 0/2,\ 1/2\)。
如果 \(\texttt A,\texttt X, \texttt o\) 的个数等于 \(k\), 我们可以枚举每种可能,对应到一个确定的三进制数 \(n\),对询问的贡献是 \([x^n]C(x)\)。
当 \(k\) 比较小时,这种 \(2^k\) 的做法已经可以能过回答一个询问了。
如果 \(k\) 较大呢?设 \(f_S\) 表示当前位限制为 \(S\) 的方案数,注意到 \(f_{\{0 \}} = \dfrac{f_{\{0, 1\}} + f_{\{0, 2\}} - f_{\{1, 2\}}}{2}\)。
\(\vert S\vert = 2\) 相当于钦定某个值不能选,\(3^{w - k}\) 枚举 \(\texttt O,\texttt a, \texttt x\) 对应的情况,现在要求 \(x + y = z\) 满足 \(z_i\) 钦定不能取哪个值。
时间复杂度 \(O(\min(2^k, 3^{w - k}))\)。
考虑上面遗留下的两个问题。
-
给定一个三进制数 \(X\),求 \(a_i + a_j = X\) 的方案数,\(a_i \in \{0, 1\}\)。
记 \(f_x = \sum [a_i = x]\),目的是求 \(F\) 的加法卷积 \(F^2\),当然可以无脑 ntt,但是有更巧妙的办法。
考虑 \(w = 1\),那么 \(f_2 = 0\):
将 \(f\) 变换到 \(\hat{f}\) 令 \(\hat{f}_2 \gets f_1 + f_0,\ \hat{f}_1 \gets f_1,\ \hat{f}_0 \gets f_0\)。
现在使 \(\hat{F} \gets \hat{F} \cdot \hat{F}\),其中 \(\cdot\) 表示对应位相乘。
现在 \(\hat{f}_0\) 表示从多重集 \(\{f_0\cdot 0, f_1\cdot 1\}\) 选出两个数相加为 \(0\) 的方案数,同理 \(\hat{f}_1\) 表示两个数相加为 \(2\) 的方案数。
\(\hat f_2\) 稍有不同,两个数之后可以是 \(0, 1, 2\),减掉 \(\hat f_0\) 和 \(\hat f_1\) 后就是相加为 \(1\) 的方案数。
现在要获得最终结果,\(f_0 \gets \hat f_0, f_1 \gets \hat f_2 - \hat f_1 - \hat f_0,\ f_2 \gets f_1\)。
考虑 \(w = 2\),初始所有包含 \(2\) 的 \(f\) 都为 \(0\):
从低到高考虑每一位 \(i\),把第 \(i\) 位为 \(0/1\) 的 \(f\) 贡献到第 \(i\) 位为 \(2\),其他位全部相同的数上。
最后考虑一个 \(f\) 存了哪些位置的方案数,例如 \(f_{22_3} = \{11_3, 10_3, 01_3,\ 00_3\}\)。
现在把 \(f\) 对应平方起来。
从低到高做还原操作,一位一位使方案数归位。
设 \(f(i, s)\) 表示
对于任意 \(i\),如果 \(p\) 的第 \(i\) 位是 \(0\),那么在没归位之前,\(f_{p + 2\cdot 3^i} = f_{p} \cup f_{p + 3^i}\land f_{p} \cap f_{p + \cdot 3^i} = \emptyset\)。
不难注意到 \(p, p + 3^i, p + 2 \cdot 3^i\) 只有第 \(i\) 位有区别,
\(f_p\) 表示 \(0 \sim i - 1\) 位和 \(p\) 相同,第 \(i\) 为两数相加等于 \(0\) 的方案数。
\(f_{p + 3^i}\) 表示 \(0 \sim i - 1\) 位和 \(p + 3^{i - 1}\) 相同(实际就是和 \(p\) 相同),第 \(i\) 为两数相加等于 \(2\) 的方案数。
\(f_{p + 2\cdot 3^i}\) 比
-
给定一个三进制数 \(X\),要求 \(a_i + a_j\) 的每一位都和 \(X\) 不同,求方案数。

浙公网安备 33010602011771号