丶濐剘糢擬賽訂㊣郃雧灬
前言
我们总是在现实中寻找虚拟,又在虚拟中寻找现实。
唯有无形之物方能在时光的洪流中永不褪色。
聚会
首先,答案函数关于 \(k\) 显然是凸的,所以我们可以先枚举一个汇合点 \(i\),再二分斜率。
考虑到 \(\text{check}\) 需要判断到 \(i\) 第 \(k\) 近的点到 \(i\) 的距离是否小于某个值。
这其实是点分树的经典运用,我们预处理出点分树,开两个大小为 \(O(n\log_2n)\) 的数组分别存每个重心管辖范围内到自己的信息和到上级重心的信息。
然后再预处理每个点到自己上面每层重心的距离。
利用这些信息,我们可以实现 \(O(\log_2n)\) 回答到某个点距离小于给定值的点的个数(用这个去 \(\text{check}\)!!!)。
也可以实现 \(O(\log_2^2n)\) 回答到某个点第 \(k\) 近的点的编号或者距离(不要用这个去 \(\text{check}\)!!!)。
量子计算
题目中的“部分复制”可以看作是概率,不过直接数方案也是可以的。
由于序列每时每刻都是排列,考虑维护一个二维矩阵 \(f\),其中 \(f_{i,j}\) 表示 \(a_i>a_j\) 的概率,那么就有 \(E(a_i)=\sum_{j=1}^n f_{i,j}\)。
询问即为求若干行的和。
修改都可以表示为整行整列的交换或者赋值。
注意到 \(m\) 很小,所以矩阵中只有很少的行和列是被修改过的,可以进行离散化。
最后可以直接维护,只不过比较复杂,可以用树状数组,也可以不用。
\(\text{Fibonacci}\) 串
我们注意到这个串不会出现连续三个相同的字符,所以按照子序列匹配的流程,当 \(|S|>3|t|\) 时,\(t\) 一定作为子序列出现在 \(S\) 中。
进一步地,不难证明 \(|S|>3|t|\) 后再随便扩展几轮便可以让 \(S\) 包含答案串。
接下来的问题就成了要在一个 \(\text{Fib}\) 串上找一个最短的区间使得其包含 \(t\) 作为子序列。
我们需要枚举起点,然后预处理一个特殊的倍增:令 \(f_{i,j}\) 表示从 \(t_i\) 开始,经过一个 \(S_j\) 最多可以匹配到 \(t\) 的哪一位。
对于 \(S\) 串的每一个后缀,都可以拆出 \(\log n\) 个完整的极长 \(\text{Fib}\) 串,这个可以把整个串拍到一个和线段树类似,只不过按照 \(\text{Fib}\) 串划分左右儿子的结构上来证明。
若经过当前 \(\text{Fib}\) 串后仍然没有匹配完 \(t\) 的全串就直接跳,这部分复杂度为 \(O(\log n)\)。
否则就枚举经过一个更小的 \(\text{Fib}\) 串,这部分枚举的串的长度会一直减小,复杂度也为 \(O(\log n)\)。
故总复杂度为 \(O(n\log n)\)。
\(\text{Kraniki}\)
设能到平台 \(i\) 的平台有 \(c_i\) 个(包含 \(i\)),那么 \(i\) 想要产生贡献,出现时间就必须要在当中排最小,概率为 \(\frac 1 {c_i}\)。
根据期望的线性性,答案为 \(\sum_{i=1}^n \frac 1 {c_i}\)。
考虑如何求 \(c_i\)。
如果将每个平台向左上方和右上方能到自己的平台连边,就变成了一个传递闭包问题。
众所周知传递闭包在一般图上是没有优于 \(O(\frac {n^3} w)\) 的传统算法的。
不过这是一个平面图,在很多平面图上,一个点的可达集能用特殊的形式来表示,比如记录 \(l,r\) 表示可达范围。
这道题中,考虑从每个平台开始一直向上跳,本质上是不断扩展自身左右端点的过程,直到跳到某个被上方平台完全覆盖的位置就停止。
每个平台的停止高度是好求的,求出来后,可以考虑对左右端点分开倍增向上跳,跳的过程中用另一个倍增数组计算代价即可。
时间复杂度 \(O(n\log_2n)\)。
染色
这题很有趣。
考虑怎样的一个最终状态是能涂出来的。
大概就是对于原序列中每个位置钦定一个可空的最终覆盖区间,然后这个区间的相对顺序要和原序列一样。
然后为了要本质不同,所以某个颜色当前次出现和上一次出现中间不能全为空。
我们发现如果已知非空区间个数,可以用组合数算出来最终的方案数。
所以说设 \(f_{i,j}\) 表示考虑了序列的前 \(i\) 个位置,选了 \(j\) 个,用前缀和优化即可做到 \(O(n^2)\) 的时空复杂度。
注意到题目要求模 \(2\),这意味着我们只需要存 \(01\),使用 \(\text{bitset}\) 可以做到 \(O(\frac {n^2} w)\)。
但是这依然超出了空间限制。
由于每种颜色新一次出现之后,其上一次出现的位置就没有用了,所以空间复杂度可以压缩到 \(O(\frac {nm} w)\),足以通过。
山峦
赛时正解没有调出来太伤心了。
注意到每一行都需要满足单调不增,同时值域范围只有 \(10\),列数也只有 \(10\)。
用组合数可以算出每行状态数最多只有 \(5\times 10^4\) 左右的量级。
考虑 \(\text{DP}\),如果像轮廓线一样每次加一个就不太好利用上述每行状态数较小的性质。
所以可以每次转移一整行,发现限制是每列对应位置需要满足偏序关系,本质上是一个高维后缀和,直接做即可。
由于还要记录已经填过的位置的权值和,所以一共要做 \(O(nm)\) 次高维后缀和,单次是 \(10\times 50000\) 的运算量。
算出来很大,但是实现的时候注意让内层循环访问连续,实测跑得非常快。
\(\text{divide}\)
朴素 \(\text{DP}\) 的转移条件是 \(i-j \geq \max_{k=j+1}^i a_k\),用普通的数据结构并不好优化。
考虑 \(\text{CDQ}\) 分治优化 \(\text{DP}\),每次钦定最大值在某一侧,双指针另一侧合法区间,操作相当于是区间加、查询区间和,用差分以及前缀和就能解决。
这里由于限制和最大值相关,所以用笛卡尔树也是可以的,这部分两种方法都能做到 \(O(n\log_2 n)\)。
对于有修改的情况,很直接的想法是把上述 \(\text{DP}\) 再倒着做一遍,记正着的为 \(f\),倒着的为 \(g\)。
那么若修改位置 \(x\),枚举区间 \([l,r]\) 满足 \(l\leq x\leq r\),若将 \(a_x\) 改为 \(1\) 后区间 \([l,r]\) 合法,则对 \(ans_x\) 产生 \(f_{l-1} g_{r+1}\) 的贡献。
这里的区间合法性判断和上面的转移条件其实是一样的,所以我们继续考虑分治。
分治算相比改之前方案数的增量或者直接算答案都是可以的,这里以增量为例。
注意到只有修改前缀 \(\max\) 变化的位置才会产生新的合法区间,且修改所有前缀 \(\max\) 变化位置所导致前缀 \(\max\) 的变化区间总长度是 \(O(n)\) 的。
所以暴力算所有位置修改后的贡献,减去修改前的贡献即为增量。
这部分和第一部分类似,也可以做 \(O(n\log_2 n)\)。
\(\text{Knocker}\)
很牛的题啊,找性质和后面的 \(\text{DP}\) 都很牛。
首先,称一个数 \(x\) 对 \(m (0<m \leq x)\) 取模为有效取模,那么显然,每次有效取模之后必然使得 \(x\) 至少减半。
其次,考虑单个数 \(x\) 经过若干次取模最终变为了 \(y\),那么我们一定可以找到一个 \(m\) 满足 \(\lceil {\frac x 2} \rceil \leq m \leq x\),使得 \(x \bmod m=y\),这个 \(m\) 也是所有等价操作中能选的最大模数,因为但凡操作中模了一个比 \(m\) 大的数,最终结果就必然 \(<y\)。
进一步地,放在序列中,如果想把 \(x\) 变成 \(y\),上述操作一定是最优的,换句话说,是最不容易丢失后续序列的“自由度”的。因为只选择最大的模数进行了一次操作,对其余数的影响是最低的。
那么我们就能感觉出这个引理:
对于任意的可达序列,总存在一种方案,使得:
每个数只经历一次有效取模。
每次取模中,设模数为 \(m\),对于任意的 \(x \geq m\),均有 \(m \geq \lceil {\frac x 2} \rceil\)。
有了引理后再来模拟一下过程。
我们先把数组排序并去重,然后第一次操作必然会改变一段后缀,由于每个数只经历一次有效取模,后续这段后缀将保持不变,可以直接删去不管。
第二次操作则会改变第一次删除完成后的新序列的一段后缀,然后以此类推。
不难发现这本质上是一个分段的问题,自然可以考虑用分段形式的 \(\text{DP}\)。
注意到新一段的模数不能影响到前面分好的段,否则会违背只有一次有效取模的限制。
所以设 \(f_{i,j}\) 表示处理好了 \(i \sim n\) 这段后缀,模之后的最大值为 \(j\) 的方案数。
转移考虑枚举模数 \(k\) 和上一段的终点 \(p\):

其中 \(pos_k\) 表示第一个满足 \(\lceil {\frac {a_t} 2} \rceil \geq k\) 的 \(t\),这是为了保证引理中的第二条。
分析复杂度,因为这一次取模也不能影响到 \(i\) 之前的部分,所以有 \(k \in (a_{i-1},a_i]\)(当然还有其它限制,不过这里分析复杂度只考虑这个)。
而且 \(a\) 数组是排序去重后的,故枚举 \(i\) 和 \(k\) 的总复杂度是 \(O(n)\),枚举 \(i,j,k\) 的复杂度为 \(O(n^2)\)。
所以第三种转移的复杂度是 \(O(n^3)\)。
对于第二种转移,枚举完 \(j,k\) 之后 \(p\) 就固定了,所以仅需枚举 \(q\),复杂度也为 \(O(n^3)\)。
最后,这两种转移可以分别用两个前缀和进行优化,总复杂度不难做到 \(O(n^2)\)。
\(\text{tree}\)
需要比较困难的对于结构的观察,得出一种可以直接树形 \(\text{DP}\) 的计算生成树的方案。
这里写起来比较费劲,参考 \(20260718\) 的 \(\text{T2}\) 题解吧。

浙公网安备 33010602011771号