20250829

坐标

给出 \(n\) 个坐标 \((X_i, Y_i)\) ,你需要构造不超过 40 个正整数 \(a_1, \cdots, a_m\) ,然后对于每个 \(i\) ,构造一组向量 \(v_1, \cdots, v_m\) ,使得

  1. \(\forall 1 \leq j \leq m, v_j \in\{(-1,0),(1,0),(0,1),(0,-1)\}\)
  2. \(\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(魔王神)

https://qoj.ac/problem/6608

显然可以考虑 \(O(n \sqrt n)\) 分块,需要离线逐块处理,维护原来某个值现在被移动到了哪里,散块修改查询时暴力 \(O(\sqrt n)\) 重构块内。

一种巧妙的方法是可持久化线段树,每个 \(v\) 有一个线段树的版本,下标 \(1 \sim n\),维护区间是否有 \(\ge v\) 的值。每次修改把 \(x\) 所对应版本的 \([l, r]\) 复制到 \(x + 1\) 上。查询直接二分。\(O(n \log^2 n)\)

Eileen 的游戏

https://qoj.ac/problem/8601

\(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\) 且不发生交换的次数为:

\[\sum\limits_{1 \le i \le n, a_i = x}\left[\max\limits_{j > i} \{a_j\} \le a_i\right] = \max\left(\sum_{1 \le i < p}[a_i = x] - \sum_{p < i \le n}[a_i > x], 0\right) \]

如果只剩下 \(\le x\) 的,那么 \(> x\) 的位置会优先被 \(x\) 填上。

使用线段树维护即可。这题之前做的,隔了一段时间,写的有点抽象。

posted @ 2025-08-30 11:40  SZwinsun  阅读(9)  评论(0)    收藏  举报