三轮省集旧题新补
[CEOI 2019] Building Skyscrapers
对于 \(T=1\) 有一个构造方法:每次在和当前区域连通的格子里选择一个 \(x\) 坐标最小的格子,如果 \(x\) 相同选择 \(y\) 最小的,进行扩展。可以证明这种方式构造出的图形不会出现闭合的圈。
对于 \(T=2\),即最大化删除的字典序。注意到由上面的构造算法的存在,一个局面有解等价于棋盘格子八连通。所以就是找到非割点中且能到达无穷远处且编号最大的格子删去。问题转化为网格图删点维护割点。
我们不直接地维护黑点的删点连通性,而是维护白点的连通性。对一个黑点,它能否成为割点之和周围八个格子里白点的连通性有关,具体地,当且仅当存在以下两种情况时可以断定 x
是割点:
A#B AAA
#xB #x#
BBB BBB
其中 #
与 #
是连通的白点,A
存在一个黑点,B
也存在一个黑点。
只有黑点周围的八个白点是有用的,总数是 \(O(n)\) 的。
每次将一个黑点变为白点,由于保证了和边界连通,所以只需要对新连通的白点 check 周围的 8 个黑点。维护每个点是否和边界连通,从新加入的白点开始 dfs 拓展周围的 4 个点。
注意一些常数问题,用 cc_hash_table 而不是 map 套 map 存 id 数组。像下面就是一个优雅的写法:
struct pair_hash {
long long operator()(const pair<int, int> &p) const {
return 1ll * p.first * (int)2e9 + p.second;
}
};
cc_hash_table<pii,int,pair_hash> id;
熟记单词拼写。
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
[PA 2024] Dzielniki
我们可以加入随机扰动。设置一个随机数 \(C\),求出答案 \(+C\)。这样可以避免受到极端数据的影响,于是我们 只关心随机数据下的表现。
考虑增量,已知 \(x\bmod 2^k\),确定 \(x\bmod 2^{k+1}\)。
设 \(x\equiv x'\pmod {2^k}\)。
询问 \(2^k-x'\):若 \(k+1|d(2^k-x')\),可以推断出 \(x\equiv x'+2^k\pmod {2^{k+1}}\);
询问 \(2^{k+1}-x'\),若 \(k+1|d(2^{k+1}-x')\),可以推断出 \(x\equiv x'\pmod {2^{k+1}}\)。
上述推断是基本成立的,除非 \(d(2^k-x')\ ,\ d(2^{k+1}-x')\) 具有 \(\ne 2\) 的质因子的幂次能够凑出 \(k+1\)。但这样也没关系,递归下去判断即可。
上述底数并非固定为 \(2\),可以换成 \(3,5,7\) 之类的数,实测不如 \(2\) 优。
[UOI 2024] Zeroing the Segments
设 \(c_x\) 表示 \(\le x\) 的个数,经过一些转化可以变成区间询问 \(\max c_x-x\)。
考虑一张二分图,左部点 \(i\) 对右部点 \(j\le a_i\) 有连边,询问的是左部的失配点个数。
扫描线 \(i\),设匹配点集为 \(S\)。如果能匹配 \(i\) 则匹配;否则选出一个最小的 \(j\in S\) 删掉 \(j\) 再匹配 \(i\)。
线段树维护 \(w_i=i-c_i\),时刻保持 \(w_i\ge 0\)。用另一棵线段树二分 \(j\)。主席树维护矩形加在线单点查。