模
07.03
A
什么时候能想到数学相关啊啊啊啊
考虑以边为变量搞一个异或方程组,求自由元个数。
然后考虑转而求秩,可以用线性基求。
然后考虑缩减方程数量。
根据题解,只需要在 dfs 找到所有返祖边构成的环加入方程组,以每个点为根都 dfs 一次,可以证明可以统计到所有限制。
B
操作可逆,考虑让两者按统一标准走到一个基态。
考虑尽可能让点往深里去。
将所有点按照 \(dep\) 从大往小排序,按此顺序依次检查每个点是否能被到达。
在构造基态时,已确定的点不会再移动,因为本身就是有深到浅确定的,来的点也只是从浅处到达目标点,故已确定的不会对点的移动造成影响。
检查一个点是否能被到达,从它开始深搜,找到第一个存在有人的邻居的点(点本身无人)。
若只有一个邻居有人,直接让那个人走到目标。
否则我们再实现一个检查一个点能否“向下”的函数,这里的下是根据我们传入的父节点决定的。
实现就是检查有没有能往下走的儿子,对儿子中造成限制的点递归判断它能否“向下”。
然后把造成限制的点都“下移”了就能让某个人走到目标了。
07.04
A
考虑先按最低标准跑一遍最短路,如果要求比这个还有则不可能。
否则我们选择一条最短路增大其上的最长边,把这条路径补成要求长度。
然后重复这个过程直到最短路等于要求长度。
虽然看上去是 \(O(n^2\log n)\) 实际上最坏也是 \(O(n^2\log n)\) 但是数据足够水。
B
我们可以感知到最后 \(a\) 大约是有若干长至少 \(k\) 的最小段,然后往两边递增。
然后我们考虑去 dp 这个形式。
设 \(f_i\) 表示 \([i - k + 1, i]\) 是要求的最小段前面跟着一段下降段的前提下,前 \(i\) 项和的最大值;\(g_i\) 是前面反正有一段最小段,当前处于上升段的前提下,前 \(i\) 项和的最大值。
然后转移时从 \(i - k\) 往前扫,用 \(f_j\) 更新 \(g_i\),贡献是后缀 \(\min\) 的和;从 \(i\) 往后扫,用 \(g_i\) 更新 \(f_j\),贡献是前缀 \(\min\) 的和。
虽然看上去是 \(O(n^2)\) 实际上就是 \(O(n^2)\) 但是小常熟直接 \(1.3s\) 过 \(5\times 10^4\)。
07.05
A
先考虑第二条限制,在这里无解就是存在一个环异或和不为 \(0\)。
然后对每个连通块在 dfs 树判一下返祖边即可。
然后 dfs 树上其实是吧每个点都表示成了根异或上一个值。
考虑字典序最小对于每个连通块就是最小化编号最小的点。
所以现在只要解决:
给定若干限制 \(l_i \le x \oplus c_i \le r_i\),要求最小化 \(x\)。
正常肯定是考虑在 Trie 树上逐位确定然后 \(O(1)\) 或 \(O(\operatorname{polylog})\) check 什么的吗。
懒得动脑直接搜。
我的天哪深搜大人,\(3s\) 实现 \(300ms\) 不到就过了?
B
空↑指↓针↑驱↓蚊↑器↓
考虑对于 he 就是每回合稳定增加一个 s 嘛。
一个思路就是拿数据结构维护其他字符和 he,然后 he 的贡献是一次函数,别的贡献常数,然后在数据结构上二分什么的。
唯一麻烦的就是 hihihis 和 hihihihe 这种,因为这个玩意变化不规律。
我们考虑对于上述结构每两回合就能消掉一个 hi,那么全局我们只需要共 \(O(n)\) 次操作能把 hi 全毙掉。
所以我们前 \(O(n)\) 回合把 hi 消去。
我们要维护 hihihis、hihihihe、he、其他字符。
然后每次操作 hihihis -> hihihe + r,hihihihe -> hihihis + he。
所以每次操作就是更改点的信息并且插入点的过程,更改信息和插入点直接平衡树维护一下。
询问直接在平衡树上二分。
你已经会这道数据结构了,写吧。
A
如果没有限制这种配对问题都是顺序小于乱序小于逆序。
我们猜测一定可以顺序完成配对。
令 \(a_0 = -\infty, a_{n + 1} = +\infty\),那么 \(a_i\) 的管辖范围是 \([\lfloor \frac{a_{i - 1} + a_i}{2}\rfloor + 1, \lfloor\frac{a_i + a_{i + 1}}{2}\rfloor]\),记作 \([l, r]\),如果 \(b_i\) 在这个范围内就可选,显然 \(a\) 的管辖范围随着别的数被删除只会扩大,所以 \(i\) 一旦可选之后就一直可选。
用链表维护 \(a\),用队列存可选的 \(i\),每次删除 \(i\) 检查 \(pre_i\) 和 \(nxt_i\) 能否入队。
写一发交上去过了说明确实可以顺序完成配对。
考虑如果某个时刻卡住了(不存在可删除点),那么 \(b_1 > r_1\),\(b_n < l_n\),那么从 \(1\) 到 \(n\) 一定存在一个过程由 \(b_i > r_i\) 到 \(b_{i + 1} < l_{i + 1}\),注意 \(r_i + 1 = l_{i + 1}\),则 \(b_i > r_i = l_{i + 1} - 1 \ge b_{i + 1}\),矛盾。
所以任意时刻总存在可删除点。
B
考虑 DP 前缀异或和数组的形态。将前缀异或和数组的二进制表示视为一个 \(m\) 行 \(n + 1\) 列的 01 矩阵(每一列代表一个数的二进制,列号从 0 开始编号)。
称原数组所有数的异或和,也就是二进制矩阵的最后一列为 S。
一行一行从高位到低位考虑这个矩形,发现条件大概是一个分治结构。比如说,对于最高位,假设 S 的这一位是 1,那么一行的形态一定是 000011111,将数组分割成了两半,两半之间的那个间隔一定满足了前缀后缀异或和的偏序限制,所以两半之间的方案就基本独立了;如果最高位对应的 S 的这一位是 0,那么可以发现最高位一定要全部是 0,否则不可能满足偏序限制。
把整个分支结构倒过来考虑,称最后被这样的分治结构划分出来的东西为块,从低位到高位做,一开始一定有 \(n + 1\) 个块,我们只需要知道有多少个块而不具体为每个块赋值 0/1,每次往高位推进一位的时候,分讨S对应位是否为 1,如果是 1,考虑合并若干个相邻两个块(相当于前面一个块赋值为0后面一个块赋值为1),而且需要保证开头块为 0 结尾块为 1;否则 S 对应位为 0,这一位不会分裂结构,所以不改变块数。
利用组合数稍微计算一下系数,矩阵乘法优化即可。
07.06
A
日常签到。
首先我们比较喜欢直线,看看与 \(s\) 有关的函数有没有一次的:
\(v^2 = v_0^2 + 2a\cdot (s - d)\)
那么一个点答案是 1 就说明 \(\exists j,v_i^2 + 2a_i \cdot (s_j - d_i) > v_j^2\)
签到题不打暴力我觉得不合适。
注意到 \(a\) 较小,我们直接对每个 \(a\) 分别做,那么上面的式子就是 \(\exists j,v_i^2 - 2a \cdot d_i > v_j^2 - 2a \cdot s_j\)。
从后往前扫时维护一下后缀最小值就好。
特别的,可以先跑一遍单调栈找出最有用的若干点,当一个选手比你小还比你强。
需要至多 \(10^8\) 次运算。
其实考场上忽略了 \(T \le 6\) 次多测,但是最后仍跑的飞快。
B
数据结构。
10k 代码调一下午加半晚上什么实力。
最怕的暴力和代码和答案分别是三个不同的数。
答案不超过 \(3\)。
若 \(u\) 两侧同时存在 \(> val_u\) 或 \(< val_u\) 的数,显然可以在两侧分别操作然后最后操作一遍。
否则同侧中与 \(u\) 大小关系相同,\(u\) 向两侧各操作一次即可。
所以只需检查答案是否 \(\le 2\)。
- 答案为 \(0\):只有 1 个点,\(x = y\)。
- 答案为 \(1\):\(\max = val_u\) 或 \(\min = val_u\)。
- 答案为 \(2\):最后一步操作一定可以是全局操作,所以上一步要使得 \(\max = val_u\) 或 \(\min = val_u\)。
以最后一步是全局 \(\max\) 为例:上一步要操作所有 \(> val_u\) 的数,记最左边的 \(> val_u\) 的数为 \(l\),最右边是 \(r\),那么若 \(u\notin [l, r]\) 或 \([l, r]\) 内最小值是 \(val_u\) 则答案为 \(2\)。
最后一步是 \(\min\) 同理。
关于 \(k\) 邻域加操作使用 k-猫猫虫剖分,里面是一个 \(O(K \log n)\) 链,\(O(K)\) 子树,\(O(K)\) 单点邻域的剖分。
Bonus

|| @KinNa_Sky : 玩 9 玩的说是
我现在才看懂 37 的名字qwq(或许还没完全懂)


浙公网安备 33010602011771号