2025.9.13 NOIP 模拟赛 题解

比赛

订正

T1 P130011 句法分析

题意

给定 \(a_{1\sim n}\)\([i,i]\) 满足条件 \(a_i\),有 \(m\)\((p,q,r)\),若 \([l,k)\) 满足条件 \(q\)\([k,r]\) 满足条件 \(r\)\([l,r]\) 满足条件 \(p\),求 \([1,n]\) 满足哪些条件,\(n\le 100,m\le300\)

分析

\(f_{l,r,s}\) 表示 \([l,r]\) 是否满足 \(s\)

容易做到 \(O(n^3m)\)

可以 std::bitset 优化到 \(O(\frac{n^3m}\omega)\)

代码

T2 P130012 树上前 k 大菊花

题意

给定一棵 \(n\) 个点的树,定义 \((u,s)\) 为一个菊花当且仅当 \(u\) 为树上一点且 \(s\)\(u\) 邻居的子集,且 \(|s|\ge 3\),给定 \(a_{1\sim n}\),定义一个菊花 \((u,s)\) 的权值为 \(a_u+\sum_{v\in s}a_v\),将所有菊花按权值从大到小排序,求第 \(k\) 大菊花的权值,\(n,k\le3\times10^5,|a|\le10^9\)

分析

先考虑一个结点 \(u\),设其邻居集合为 \(N\),令 \(a_{1\sim l}\)\(\{a_x\mid x\in N\}\) 从大到小排序后的结果

对于一个大小 \(3\le t\le l\),考虑如何按总和从大到小枚举 \(a\) 大小为 \(t\) 子集

\(t\) 个指针依次指向 \(t\) 个被选择的元素,初始位于 \([1,t]\) 且都不固定

要求出下一个,要么将最后一个没有固定的指针向后移动一位(要求不能碰到已固定指针或超出范围),要么固定最后一个指针并令前一个指针向后移动一位

\((u,p,p_1,p_2)\) 表示该状态,其中 \(p\) 为倒数第二个未固定指针的位置,\(p_1\) 为最后一个未固定指针的位置,\(p_2\) 为第一个已固定指针的位置(若不存在则设为 \(l+1\)),则转移到 \((u,p,p_1+1,p_2)\)(满足 \(p_1+1<p_2\))或 \((u,p-1,p+1,p_1)\)(满足 \(p\ne 0\)\(p+1<p_1\)

用堆维护所有待扩展的四元组,容易做到 \(O((n+k)\log n)\)

代码

T3 P130013 相关聚类

题意

给定一棵基环树,边权为 \(-/+\),对于每个 \(k=1\sim n\),求出将原树划分为 \(k\) 个连通块的最小权值,其中一种划分方式的权值为两端连通的 \(-\) 边数加上两端不连通的 \(+\) 边数,\(n\le3\times10^5\)

分析

逆序考虑,初始各自为一个连通块,每次选择一条边把两端并起来,可证最优解一定可以转化为该过程

先考虑树的情况,显然优先选 \(+\) 边,其次选 \(-\) 边最优,这样初始代价为 \(+\) 边数,选 \(+\) 边时代价减一,选 \(-\) 边时代价加一

然后考虑只有环的情况,显然有一条边不会用到,在树的情况的基础上,若剩下的为 \(+\) 边则最后一条边代价额外减一,否则额外加一,显然树的贪心策略仍然适用

考虑基环树的情况

环部分剩下的边为 \(+\) 当且仅当环上所有边都是 \(+\),显然优先选择环边,然后选择 \(+\) 树边,最后选择 \(-\) 树边最优

若环上存在恰好一条 \(-\) 边,则环部分选择的最后一条边(显然它是 \(+\) 边)代价为 \(0\),因此优先选择 \(+\) 树边,然后选择 \(+\) 环边,最后选择 \(-\) 树边最优

若环山存在 \(>1\)\(-\) 边,则环部分选择的最后一条边(显然它是 \(-\) 边)代价为 \(-2\),因此优先选择 \(+\) 边,然后选择树上 \(-\) 边,最后选择环上 \(-\) 边最优

时间复杂度 \(O(n\log n)\),容易做到 \(O(n\alpha(n))\)

代码

T4 P130014 最小生成树

题意

给定一棵 \(k\) 点的有根树,定义 \(dep_u\) 为结点 \(u\) 到根的距离,树上有 \(n\) 个互不相同的关键点,分别在 \(x_{1\sim n}\),各自有权值 \(a_{1\sim n}\),给定 \(w_{1\sim m}(m\ge \max dep)\),定义 \(\text{dis}(i,j)=a_i\oplus a_j\oplus w_{dep_{\text{lca}(a_i,a_j)}}\),求出 \(\sum_i \min_j \text{dis}(i,j)\)\(n\le10^5,m\le3\times10^5\)

分析

考虑 \(\text{DSU on tree}\)

考虑处理子树 \(u\)\(u\) 本身视为一个轻儿子

设子树分别为 \(S_{1\sim t}\),重子树为 \(S_w\)\(S_s=\{S_i\}\cup S_w\),则需要对于每个 \(u\in S,S\in S_s\),求出 \(\min_{v\in T,T\in S_s,T\ne S} \text{dis}(u,v)\)

轻子树之间的贡献直接用 \(\text{Trie}\) 计算即可,时间复杂度 \(O(\sum |S_i|\log V)\),这部分总时间复杂度为 \(O(n\log n\log V)\)

重子树对轻子树的贡献,处理每个子树时返回它所在子树内所有点的 \(a\) 构成的 \(\text{trie}\),枚举轻子树内的点,在重子树的 \(\text{trie}\) 上查询即可,总时间复杂度 \(O(n\log n\log V)\)

轻子树对重子树的贡献,全局维护一棵 \(\text{Trie}\),扫到一个结点时,将轻子树中的 \(a\) 异或当前结点对应 \(w\) 插入树中,处理重子树,然后撤销,到单个结点时在树中查询贡献,这部分总时间复杂度 \(O(n\log n\log V)\)

总时间复杂度 \(O(n\log n\log V)\)

代码

比赛结果

\(100+40+0+40\)\(\text{rk}81\)

posted @ 2025-09-15 11:21  Hstry  阅读(20)  评论(0)    收藏  举报