20250829
坐标
给出 \(n\) 个坐标 \((X_i, Y_i)\) ,你需要构造不超过 40 个正整数 \(a_1, \cdots, a_m\) ,然后对于每个 \(i\) ,构造一组向量 \(v_1, \cdots, v_m\) ,使得
- \(\forall 1 \leq j \leq m, v_j \in\{(-1,0),(1,0),(0,1),(0,-1)\}\)。
- \(\sum_{j=1}^m a_j v_j=\left(X_i, Y_i\right)\)。
\(|X_i|, |Y_i| \le 10^9\)。要求 \(1 \le a_i \le 10^{12}\)。
不妨 \(X_i, Y_i \ge 0\)。
若 \((X_i + Y_i) \bmod 2\) 不全相等,则无解,否则总能找到一组解。
如果分别做二进制划分只能做到 \(X_i, Y_i < 2^{20}\):
\(\forall 0 \le i \le 19\),放 \(2\) 个 \(2^i\)。若 \(X_i + Y_i\) 是奇数,则减少一个 \(1\)。
从低位往高位,每一位如果两边都有就直接放,两边都没有就自己抵消掉,否则把剩下的 \(2^i\) 和原来的一个 \(2^{i - 1}\) 作差表示一个 \(2^{i - 1}\)。
尝试把两边合起来做,希望每个 \(2^i\) 都能恰好出现一次,那么需要保持两侧剩下部分的总和当前位为 \(1\)。
需要 \(2^0\) 到 \(2^{30}\) 之间 \(2\) 的次幂各一个。初始如果第 \(0\) 位不是 \(1\) 则额外添一个 \(1\)。最坏 \(32\) 个数。
Decent Of Dragons(魔王神)
显然可以考虑 \(O(n \sqrt n)\) 分块,需要离线逐块处理,维护原来某个值现在被移动到了哪里,散块修改查询时暴力 \(O(\sqrt n)\) 重构块内。
一种巧妙的方法是可持久化线段树,每个 \(v\) 有一个线段树的版本,下标 \(1 \sim n\),维护区间是否有 \(\ge v\) 的值。每次修改把 \(x\) 所对应版本的 \([l, r]\) 复制到 \(x + 1\) 上。查询直接二分。\(O(n \log^2 n)\)。
Eileen 的游戏
有 \(n\) 位英雄和 \(n\) 个怪物,第 \(i\) 位英雄的能力是 \(a_i\) ,第 \(i\) 个怪物的实力是 \(b_i\) ,保证 \(a_i, b_i\) 两两不同且它们构成一个 \(1 \sim 2 n\) 的排列。
现在,每位英雄将会挑选一个怪物与其对战。形式化地说,他们会选定一个排列 \(p\) ,使得第 \(i\) 位英雄对战第 \(p_i\) 个怪物。英雄会赢得战斗当且仅当其能力高于怪物的能力。
在战斗之后,我们考虑所有获胜的英雄的编号 \(S \subseteq\{1,2, \cdots, n\}\) 。
\(q\) 次询问,每次给定整数 \(l, r(0 \le l, r \le n)\),求存在多少集合 \(S_i\) ,满足 \(|S_i| \in[l, r]\),且存在一个排列 \(p\) 满足在这种对战情况下获胜英雄的编号集合为 \(S\) 。
\(1 \le n \le 5000\),\(1 \le n \le 10^6\),答案对 998244353 取模。
这个询问次数,显然应当求出 \(|S|\) 的每一种取值的方案数。下面计数 \(|S| = m\) 的合法方案数。
显然对 \(a\) 和 \(b\) 分别排序,用 \(S\) 中的元素从小到大去击败 \(b\) 的前 \(m\) 小,剩下的从小到大被 \(b\) 剩下的击败。设有 \(c_i\) 个 \(j\) 满足 \(b_j < a_i\)。
考虑从 \((0, 0)\) 走到 \((m, n - m)\),每次向右或向下移动一格,禁止到达一些点,求方案数。假设向下一步对应 \(\vec{v_1} = (1, 0)\),向右一步 \(\vec{v_2} = (0, 1)\)。
- 如果走了 \(i\) 步到达 \((t, i - t)\),且 \(t > c_i\) 即 \(b_t > a_i\),这是非法状态。那么禁止掉 \((c_i + 1, i - c_i - 1)\)。
- 如果走了 \(i - 1\) 步到达 \((i - 1 - t, t)\),且 \(t < c_i - m\) 即 \(b_{m + t + 1} < c_i\),那么将永远无法往右走。禁止掉 \((i - c_i + m, c_i - m - 1)\)。
画图观察发现,上述禁止的点覆盖了所有非法情况,禁掉这些就是充要的。然后可以 \(O(n^3)\)。
如果非法位置存在于这个矩形之内,那么前一类非法位置需要 \(c_i + 1 \le m\),后一类非法位置需要 \(c_i \ge m + 1\)。因此存在第 \(d\) 步,使得这步之前没有第二类位置,这步之后没有第一类位置。\(d\) 为最后一个满足 \(c_i \le m\) 的下标。
那么拆开来分别 DP 再合并即可。
小 Z 与函数
int a[200005]; int get(int n) { int res = 0; for (int i = 1; i <= n; i++) { int vs = 0; for (int j = i; j <= n; j++) if (a[i] < a[j]) swap(a[i], a[j]), res++, vs = 1; res += vs; } return res; }有一个长度为 \(n\) 的序列 \(b\)。对于 \(b\) 的每个前缀,将其作为一个序列 \(a\),求使用以上代码得到的函数值。
\(1 \le n \le 2 \times 10^5\)。
不考虑本轮是否发生至少一次交换,答案就是严格顺序对数,直接树状数组即可。
如果第 \(i\) 轮时,\(a_i\) 是后缀最大值,那么不会发生交换。
对于每种 \(a_i = x\),找到第一个 \(a_p < x\) 的 \(p\),那么第一个位置是 \(x\) 且不发生交换的次数为:
如果只剩下 \(\le x\) 的,那么 \(> x\) 的位置会优先被 \(x\) 填上。
使用线段树维护即可。这题之前做的,隔了一段时间,写的有点抽象。

浙公网安备 33010602011771号