The 4th Universal Cup. Stage 25: Grand Prix of Zagreb(无 I)

又坑队友了🐖。

A. Arrow Array

首先把两个限制统一一下,认为 \(-a_i\) 的意思是至多有 \(n - a_i\) 个箭头指向这个分界线,这样所有的限制就只与指向这个分界线的箭头有关了。

\(c_i\) 表示指向 \((i, i + 1)\) 间的分界线的箭头数量(这里扩展出 \(c_0, c_n\)),发现只要满足以下条件 \(c_i\) 就合法:

  • \(|c_i - c_{i + 1}| = 1\),可以据此判断出 \(i + 1\) 位置的箭头。
  • \(c_0 + c_n = n\),因为 \(c_0\) 为向左的箭头数,\(c_n\) 为向右的箭头数。

考虑如果固定了 \(c_0 = x\) 怎么判断是否有解,可以递推到 \(i\)\(c_i\) 可能的值,会发现是一段区间 \([l, r]\) 内奇偶相同的值,于是可以 \(\mathcal{O}(1)\) 递推 \([l, r]\) 的变化。

\(l_{x, i}, r_{x, i}\) 表示 \(c_0 = x\) 时递推到 \(i\) 的区间。
考虑 \(l_{x, i}, l_{x + 2, i}\) 的关系,因为 \(x + 2\) 起点就更靠上,所以不会存在 \(l_{x, i} > l_{x + 2, i}\) 的情况,\(r_{x, i}\) 也是同理的。

于是发现当 \(x\) 的奇偶固定时,\(x\) 增加 \(l_{x, i}, r_{x, i}\) 不减。

特殊的,过程中可能会遇到无解的情况,此时如果是 \(l_{x, i}\) 不能满足至多的限制,就认为是区间端点大了,之后的 \(l = r = +\infty\),如果是 \(r_{x, i}\) 不能满足至少的限制,就认为是区间端点笑了,之后的 \(l = r = -\infty\)

且最后要求的也是 \(n - x\in [l_{x, n}, r_{x, n}]\),所以可以考虑二分,若 \(n - x < l_{x, n}\) 则说明 \(x\) 应该变大,若 \(n - x > r_{x, n}\) 则说明 \(x\) 应该变小。

注意不同奇偶的 \(x\) 是不具有单调性的,需要分别二分。

时间复杂度 \(\mathcal{O}(n\log n)\)

submission

B. Big Balls

有一些分治的 \(\mathcal{O}(n \log^2 n)\) 做法,官方题解的 \(\mathcal{O}(n\log n)\) 做法很有巧思,记一下。

手玩一下会发现同时移动这个限制是可以改成以任意顺序合并的。
于是可以先按任意顺序合并出一个合并树,每个树上节点都代表一个区间 \([l, r]\) 合并出的新节点。
对于查询 \([l, r]\),在树上的结构一定也会是若干个节点,其中存在一个分界线,靠左的节点的方向是左,靠右的节点的方向是右。

因为总和是确定的,所以只考虑求解左侧节点的权值和。

考虑如果在左侧有个 \(+\infty\) 的向右的点,右侧有个 \(+\infty\) 的向左的点,让左侧的点不断向右合并直到合并到右侧 \(+\infty\) 的点,之前合并到的点都会是朝左的点。
进一步发现左侧的 \(+\infty\) 其实也是不必要的,因为可以在全局左侧加入一个 \(+\infty\),考察 \(l - 1\) 不断合并的过程,在右端点 \(> r\) 前的那一步的右端点 \(p\) 就是分界线,\([l, p]\) 就是最终向左的点。

建树后写个倍增即可。

时间复杂度 \(\mathcal{O}((n + q)\log n)\)

submission

C. Crooked Cycles

\(a_{1\sim n}\) 刻画到图上,可以令图上的每个节点 \((x, y)\) 代表有序的 \(a_{i - 1} = x, a_i = y\),若存在三元组 \((x, y, z)\) 则连边 \((x, y)\to (y, z)\) 表示可以在之后选择 \(a_{i + 1} = z\)
由此可知 \((x, y) \to (y, z) \to \cdots\to (x, y)\) 便对应着一个合法的 \(a_{1\sim n}\)

注意到对于三元组 \((x, y, z)\) 会连边 \((x, y)\to (y, z)\to (z, x)\)(另外 \(3\) 条边是类似的),这说明每个连通块都应该是个强连通分量,所以一旦存在一个长度 \(\bmod\ 3 \not = 0\) 的环就可以通过不断扩展一个三元环扩展到每个点,所以只需要从连通块任意一个点为起点 dfs 判环就是对的。

时间复杂度 \(\mathcal{O}(n\log n)\)

submission

D. Dangerous Data

学到了。

手玩一下会发现如果传递的信息是全局的一些子集信息总是有办法区分不了某些值,这说明传递的信息只能是全局信息。

再想一下传一个什么样的信息能够识别出所有的值,可选的方向挺少的,试一会错发现能选择一个质数 \(p > 10^6\) 然后构造 \(\prod\limits_{i = 1}^k (x - a_i)\bmod p\) 这个多项式,这样只有在带入 \(a_i\) 时该式会为 \(0\)

接下来的问题是如何传递这个多项式,因为多项式度数为 \(k\),考虑直接记录下 \(k + 1\) 项的系数(\(x^k\) 系数为 \(1\))。

组合意义一下,也就是要得到选出 \(\le k\) 个数的 \(-a_i\) 乘积之和,于是可以先对 \(n + k\) 个值 dp 一下得到 \(f_{0\sim k}\),解密时对给定的 \(n\) 个值 dp 得到 \(g_{0\sim k}\)
接下来要从 \(f\)\(g\) 复原出 \(h_{0\sim k}\) 表示没出现的 \(k\) 个数的系数,通过 \(f\) 容斥一下有几个数是在 \(g\) 中出现的就好了:\(h_i = f_i - \sum\limits_{j = 1}^i f_{i - j}g_j\),其实也就是多项式求逆,因为 \(f_0 = 1\) 所以一定可以求逆。

然后把值代入多项式检验即可。

时间复杂度 \(\mathcal{O}((n + k)k + k\max a)\)

可以选择 \(p = 10^6 + 3\)

submission

E. Exchange Error

官方题解给个根号做法没绷住。

\(f_i = \max\limits_{r - l + 1 = i}\sum\limits_{j = l}^r a_j\),答案就可以写作 \(S(x) = \max\limits_{i = 1}^n f_i + ix\),可以用凸包来维护,查询只需要二分斜率。

然后来 \(f_i\),考虑分治,计算 \([l, mid]\) 的后缀和 \((mid, r]\) 的前缀合并的信息。
注意到实际上只有最后凸包上的点是有用的,所以两部分都只需要保留凸包的元素(把另一部分看作是一个定值,就只与当前部分有关了),那合并起来也只需要写一个凸包合并就行了。

时间复杂度 \(\mathcal{O}((n + q)\log n)\)

submission

F. Flipping Frenzy

是个有意思的题,不去想怎么优化线性基就做出来了。

因为矩形要求必须有角在 \(x = 1, y = 1\) 上,所以对于每种矩形只有 \(\mathcal{O}(n + m)\) 种可能的方法,一个想法是直接去建线性基,但是 \(k(n + m)\)\(nm\) 维向量求线性基显然爆了。

对于矩阵异或差分一下,考虑 \(b_{i, j} = a_{i, j}\oplus a_{i - 1, j}\oplus a_{i, j - 1}\oplus a_{i - 1, j - 1}\),这样会发现对于左上角 \((x, y)\) 大小为 \((a, b)\) 的矩阵操作后只有 \((x, y), (x + a, y), (x, y + b), (x + a, y + b)\) 的点值会改变。

这样的好处是因为 \(x, y\) 必有一个 \(=1\),这说明这 \(4\) 个点中至多 \(2\) 个点满足 \(x\not = 1, y\not= 1\)

而如果一个线性基里的向量都只有 \(2\)\(1\) 是好做的,只需要把两个 \(1\) 连边,对于每个连通块选取一颗 dfs 树,自底向上对于边 \((fa, u)\)\(u\) 在考虑完子树后点权为 \(1\) 则选择这个向量,这样 \(u\) 点权变为 \(0\)\(fa\) 点权异或 \(1\)

对于这个题也是相同的想法,考虑把 \((x, y)\) 都不为 \(1\) 的点视为主元,那么可以先去把所有主元按上述方法都消去,就只剩下 \(n + m - 1\)\(x = 1\)\(y = 1\) 的点要考虑了,这个时候再跑线性基,但发现复杂度还是不太能接受。

仔细分析一下每个向量 \(1\) 的形式,考虑 \(x = 1, y = 1\) 的情况,此时单个 \((a + 1, b + 1)\) 主元会对应 \(3\) 个次要元素 \((1, 1), (a + 1, 1), (1, b + 1)\)
而对于 \(x, y\) 有一个不为 \(1\) 的情况,例如 \(x = 1, y\not = 1\),此时主元是 \((a + 1, y), (a + 1, y + b)\),次要元素是 \((1, y), (1, y + b)\),发现这其实就是主元为 \((a + 1, y)\) 和主元为 \((a + 1, y + b)\) 的次要元素异或后的结果。

因为初始每个向量的次要元素就是主元对应次要元素的异或,消元后肯定也是如此,所以对于无主元的向量,这个向量一定是全 \(0\) 的不需要考虑。

因为题目保证了有解,主元消完后次要元素一定为 \(0\),所以可以抛去次要元素,直接对主元跑上文提到的消元方法。(不保证有解也是可以做的,只需要最后判一下次要元素是否为全 \(0\)。)

需要注意 \(x = 1, y = 1\) 时只有 \(1\) 个主元 \((a + 1, b + 1)\),可以加入一个主元 \((1, 1)\)(虽然这个主元并不合法,可以当作其是一个虚点。)

时间复杂度 \(\mathcal{O}(k(n + m) + nm)\)

submission

G. Grid Gradient

感觉不如本机挂一会 \(\mathcal{O}(nm2^{m})\) 的做法直接打表😅。

首先注意到 \(x + y\) 奇偶性相同的点点权的奇偶性也得相同,不妨假设 \(a_{1, 1}\) 是奇数,偶数是同样的。

此时因为每个奇数只有 \(1, 3\) 两种选择,偶数也只有 \(2, 4\) 两种选择,于是可以考虑插头 dp,\(f_{i, j, s}\) 表示 \((i, 1\sim j), (i - 1, j + 1\sim m)\) 的状态为 \(s\) 的方案数,每次考虑 \((i, j + 1)\) 的状态,这样就可以做到 \(\mathcal{O}(nm2^{m})\) 了。

这里不妨认为奇数 \(1\) 偶数 \(4\) 在奇数偶数里分别的编号都为 \(0\),会发现一个合法的 \((i, j, s)\) 应当满足 \([1, j]\) 中没有相邻的 \(0\)\([j + 1, m]\) 中没有相邻的 \(0\),所以合法的 \(s\) 应当是 \(\mathcal{O}(\operatorname{Fib}(m))\) 级别的(把 \(0\) 和后面的 \(1\) 直接捆绑起来看,相当于每次可以在当前合法串后加入 \(01\)\(1\),就是 fib 的转移式了)。

于是只对合法的状态做转移,可以做到 \(\mathcal{O}(nm\operatorname{Fib}(m))\) 的复杂度。

写烂了有被卡常的可能。

submission

H. Halfway Hawser

\(n = |s|\)

发现 \(t_{i, j}\) 的取值其实只与 \(i, j\) 大小有关,具体来说就是 \(t_{i, j} = \begin{cases}s_{j + 1} & i\le j\\ s_j & i > j\end{cases}\)

首先考虑 \(t_{*, 1}\),把 \(\{1, 2, \cdots, n\}\) 划分成 \(\{1\}, \{2, 3, \cdots, n\}\) 两个集合,集合内 \(t_{*, 1}\) 都是相同的,然后可以通过比较这两个集合中 \(t_{*, 1}\) 的大小关系判断出哪个集合字典序更小,就可以根据哪一侧包含了 \(\lceil n / 2 \rceil\) 这个排名来继续递归。

根据这个过程能发现未确定的排名一定是一个区间,且待选 \(t_i\) 集合的 \(i\) 也是一个区间,所以每次直接从 \(j\) 这个位置分裂计算数量继续递归都是好做的。

时间复杂度 \(\mathcal{O}(n)\)

submission

J. Jolly Janes

容斥一下转为不被选的期望数量。

\(s, t\)\(0\) 的数量分别为 \(p, q\)

那么对于一个 \(s, t\) 中均为 \(0\) 的人,依旧不被选的概率就是 \((1 - A/p)(1 - B/q)\)
根据期望的线性性,不被选的期望数量也就是每个人不被选的概率之和,加起来就行了。

注意 \(A\ge p\)\(B\ge q\) 时概率为 \(0\),这个时候可能会出现负数或者除 0 的问题。

时间复杂度 \(\mathcal{O}(n)\)

submission

K. Kempt Kale

倒着来看,后 \(i\) 个只能选出至多 \(\lfloor\frac{i}{2}\rfloor\) 个元素。

此时有一个最极端的情况就是选择 \(1, 3, 5, \cdots, 2n - 1\)\(n\) 个值。

然后会发现每个元素往前移肯定依然合法,所以限制就可以看作从前到后选的第 \(i\) 个值的位置要 \(\le 2i - 1\),于是可以维护一个前缀的大根堆,每次在 \(2i - 1\) 的位置选上最大的元素即可。

时间复杂度 \(\mathcal{O}(n\log n)\)

submission

L. Loop Land

感受一下这题大概就是个 2-sat 这样的二元变量然后一大坨限制的题,再感受一下连出来的会是个无向边,所以可以扩域并查集或者二分图染色跑一下跑出来每个变量的选择。

具体讨论一下连边,以下讨论一个点 \((i, j)\) 不同点权对应的连边情况,记 \(U, D, L, R\) 代表 \((i, j)\) 上下左右相邻的边(每条边的 \(0/1\) 状态代表是否存在),\((u, v, 0/1)\) 代表 \(u, v\) 的状态是否不同(\(0\) 相同 \(1\) 不同):

  • 0,\(U, D, L, R\) 都不存在,可以开一个 \(0\) 点代表不存在的点,\((U, 0, 0), (D, 0, 0), \cdots\)
  • 1,\((U, D), (L, R)\) 每对一定共同存在,且两对只有一对存在,\((U, D, 0), (L, R, 0), (U, L, 1)\)
  • 2,发现只需要 \((U, D), (L, R)\) 每对恰好存在一个就性,\((U, D, 1), (L, R, 1)\)
  • 3~8,不可能有边的与 \(0\) 相连,二选一的两点连一个边权为 \(1\) 的边。
  • 9,\(U, D, L, R\) 都存在,类似 \(0\) 的做法开一个 \(1\) 点代表必存在的点,\((U, 1, 0), (D, 1, 0), \cdots\)
  • A,\(L, R\) 必存在,\(U, D\) 存在恰好一个,\((L, 1, 0), (R, 1, 0), (U, D, 1)\)
  • B,\(U, D\) 必存在,\(L, R\) 存在恰好一个,类似 A 连边即可。

跑出来的状态就是构造目标。

时间复杂度 \(\mathcal{O}(nm)\)

我代码写的很🐖,我按照边建了边后没有直接构造而是反回去得到了点的状态再构造的。

submission

M. Maximum Mex

\(k = 6\)

好像有单 \(\log\) 的做法,但好像没人说具体咋做。

考虑二分 \(\operatorname{mex} \le x\),就只需要存在一条路径,其边权存在 \(0\sim x - 1\)

首先有一个做法是考虑对每个边权为 \(w\) 的边集考虑,如果只有一条边,那么可以转成两个端点在 dfs 序上的约束(有个端点要在深一点的节点的子树内,另一个端点在该节点的子树外),这就是一个矩形。

不过因为这是个边集,所以需要把所有边对应的矩形求个交再拆分成小一点的矩形,小矩形个数应该是边集平方大小的。

得到这个后就相当于是有若干个矩形,问平面是否存在一个点满足被覆盖次数为 \(x\),扫描线维护最大值即可,时间复杂度 \(\mathcal{O}(nk\log^2 n)\)

还有一个相对好写一点的做法,考虑路径必须过一条 \(0\) 边,于是先枚举一条 \(0\) 边断开拆成两个树 \(T_1, T_2\) 考虑。

这个时候可以在 \(T_1\) dfs 并在 \(T_2\) 用线段树维护一个端点为 \(T_1\) 当前节点另一个端点在 \(T_2\) 的端点被 \(0\sim x - 1\) 不同颜色的覆盖次数。
具体来说,如果在 \(T_1\) 往下走一条边 \((u, v, w)\),到 \(v\)\(w\) 这个颜色一定能覆盖住所有路径,而原本在 \(T_2\) 的点可能只能靠 \(T_2\) 已有的边权为 \(w\) 的边覆盖,把这些覆盖都去掉转而全局覆盖,这也可以在 dfs 树上考虑。
为了避免算重,\(T_1, T_2\) 中若有两条边有着相同的边权且为祖先关系,则深度更深的那条边一定是没用的。

这个做法因为要多枚举一个边权为 \(0\) 的边,所以复杂度会多一个 \(k\),为 \(\mathcal{O}(nk^2\log^2 n)\)

我写的第二种做法。

submission

posted @ 2026-06-05 10:24  rizynvu  阅读(26)  评论(0)    收藏  举报