联合省选2025Day1题解
P11830 [省选联考 2025] 幸运数字
一个直觉就是对于每个二元组,答案一定是 \([l_2,r_2]\) 的一个子区间。
然后直接对每个区间二分答案区间的左右端点,稍微优化一下可以 \(O(n\log^2 n)\)。
但是这比较蠢,因为你都知道答案区间是可能区间的子区间,那稍微再想想你就会发现答案区间其实是 \([l_i,r_i]\cap [L,R]\),这个 \([L,R]\) 就是可能的中位数的区间,然后计算答案就是线段并的长度。复杂度简单 \(O(n\log n)\)。
P11831 [省选联考 2025] 追忆
考场想法:
首先查询已经严格强于 DAG 可达性了,所以复杂度一定不低于 \(O(n^2/w)\),然后一看 \(n=10^5\),\(TL=6s\),那上限也就是这个复杂度了。
然后想了半天想到是不是可以按照 \(B\) 个修改为一块,然后攒够了暴力 rebuild,复杂度可能可以做到 \(O(nq\log n/w)\) 之类的。
但是代码写一半发现怎么 \(n=6\times 10^4\) 要跑 \(>6s\),直接放弃。
然后写了 t3 部分分回来 20min 写了 \(O(nq)\) 乱搞跑路。
正解:
考虑一个暴力,枚举可达的点,然后判断是否 \(a\in[l,r]\),求最大值。
然后考虑 bitset 维护同时满足可达且 \(a\in[l,r]\) 的点。
一个想法是 \(A_i\) 维护 \(a\geq i\) 的点的集合,但是我们发现,修改的复杂度达到了 \(O(n)\),但是查询只是一个简单的 \(O(n/w)\),这时候要想到根号平衡,考虑不要维护这么密的 \(A\),只要每 \(B\) 个维护一个,维护 \(A_i=\{j|a_j\geq B\times i\}\) 这个点集,那么单次修改就是 \(O(\frac{n}{B})\) 的,然后一次查询是 \(O(n/w+B)\) 的,这样只要 \(B=\sqrt n\) 就可以做到根号的复杂度。
然后就变成了求出这个点集里面 \(b\) 最大的那一个。我们发现,一个思路是去二分答案,然后维护 \(B_i=\{j|b_j\geq i\}\) 的点集,同样的,修改还是 \(O(n)\) 的,然后继续平衡复杂度,维护 \(B_i=\{j|b_j\geq B\times i\}\),然后在块上二分,然后块内暴力,做到 \(O(n\log (n/B)/w+B)\)。
这里让 \(B=n/w\) 可以做到 \(O\left(\dfrac{qn\logw}{w}\right)\)(如果 \(B\) 更大一些复杂度应该可以更低一些),卡常后应该可以通过。
但是二分还是比较蠢,考虑 \(B=\sqrt n\),那都只有根号块了,那直接枚举每一块,然后想一个不要 bitset 整个操作的方法就行了。
考虑现在的问题就是找到最后一个满足 \(t\cap B_i\neq\varnothing\) 的 \(i\)(设为 \(ans\)),考虑一个暴力是,枚举 \(j:1\to n\),然后维护 \(p\) 表示当前找到 \(t\cap {B_p}'\neq\varnothing\),其中 \({B_p}'=B_p\cap [1,j]\)。对于 \(p\),如果 \(t\cap B_p\cap\{j\}\neq\varnothing\),那么 \(p\to p+1\) 即可。最后 \(p-1\) 就是答案。
用人话描述就是,枚举每个点,只要其是可达点,并且在 \(B_p\) 中,意味着 \(ans\geq p\),所以 \(p\to p+1\)。
你都用 bitset 了,那这个暴力的一个直接优化就是,把 64 个位置压到 u64 里,用 \(O(1)\) 位运算判断这 \(64\) 个位置里有没有满足的,有就 \(p\to p+1\)。显然这是正确的。
所以复杂度就是 \(O(qn/w+\frac{qn}{B})\)。
然后对于块内 \(O(B)\) 暴力即可。
当 \(B=\sqrt n\) 时,复杂度 \(O\left(q\left(\frac{n}{w}+n\sqrt n\right)\right)\)。
P11832 [省选联考 2025] 图排列
题目的排列定义比较绕,简化一下题意就是你要把给出的点排成一列,使得边不交,然后输出点编号字典序最小的方案。
一开始肯定考虑简单的。AC 性质就是一颗树,一个简单的树形 dp 就是维护 \(f(x)\) 表示 \(x\) 子树的最优方案,然后注意到子树在点列上一定是一个连续段,所以只要对子树之间相对顺序进行排序即可。根据字符串拼接字典序最小的套路,即临项交换,对于两个字符串 \(S,T\),我们可以按照 \(S+T<T+S\) 进行排序。然后暴力拼接。
复杂度 \(O(n^2\log n)\)。
但是这有点蠢,因为点编号唯一,所以只要比较第一个位置就可以得出最后的顺序,进一步的,\(f(x)\) 只要记录子树内最优方案的第一个点,这样我们只要对出边按照 \(f\) 排序即可,这样复杂度是 \(O(n\log n)\) 的。
做到这里就有 \(24\) 分了。
然后考虑 C 性质,即森林。首先要明确的是,这时候,不同连通块之间还可以出现包含关系,形成了一个树形结构。
所以考虑沿用 AC 性质求出所有连通块的答案,然后考虑合并。
首先贪心地找到字典序最小的连通块,然后加入其第一个点。接下来考虑是加入第二个点,还是加入一个新的连通块的第一个点。如果是加入新的联通块,那么 dfs 下去继续做,否则加入这个点。
这样合并的复杂度 \(O(n)\)。这样做到这里就有 \(44\) 分了。拼上暴力就是 \(52\) 分。这也是场上大部分人的分数。
然后考虑不是树怎么做。首先求出连通块的点双,建出圆方树,问题就变成定向圆方树上的边。
对于方点,出边顺序排序和上面一样,但是对于圆点则不同,因为要满足边不交,考虑什么方案可以满足该限制。
首先点双有哈密顿回路,找到一个哈密顿回路后,把这个回路变成一个大圆,我们发现边不交意味着该点双内存在恰好一条回路,否则边必定相交。然后考虑求出该哈密顿回路。
正常求这个问题是 NPC 的,但是这样的图我们有一种特殊的方法求出该回路。一个类似的题目是 CF1656I,在这道题里面我们用到了一种广义串并联图方法,简单来说,该方法总结为三种操作:删一度点,缩二度点,叠合重边。
一个实现该方法的流程是:
- 维护 \(\deg\leq 2\) 的点集 \(q\)。
- 找到 \(q\) 中某个点 \(u\),将 \(q\to q-\{u\}\)。
- 对 \(u\) 执行操作:
- 若 \(\deg u=1\),执行“删一度点”操作,找到唯一连边 \((u,v)\),删除,更新 \(\deg v\),若 \(\deg\leq 2\) 则加入 \(q\)。
- 若 \(\deg u=2\),执行“缩二度点”以及“叠合重边”操作:
- 找到连边 \((u,a)(u,b)\),删去。(缩二度点)
- 加入 \((a,b)\):若已经存在该边,那么不管,否则连接 \((a,b)\)。
- 更新 \(\deg a,\deg b\),若 \(\deg\leq 2\) 则加入 \(q\)。
- 若点集不为空,返回第二步。否则结束该方法。
如果对这个点双图执行该方法,我们发现除了最后一次删除的边外,其他的边一定是在环上的。
一种得到环上的边的做法是,记录加入 \((a,b)\) 时哪一些边失败了,由于图的特殊性,这些边一定不在环上。另外一种做法是记录缩二度点的事件,倒序插入,这样也可以得到原来的环。
注意到点双内的顺序最多有两种,只能在环上顺时针或逆时针走,所以贪心判断一下就出来了。然后就是把圆方树当做原树做就行了。复杂度 \(O(n\log n)\)。

浙公网安备 33010602011771号