专栏文章

NOIP 8/11 题解

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mioecl2f
此快照首次捕获于
2025/12/02 17:49
3 个月前
此快照最后确认于
2025/12/02 17:49
3 个月前
查看原文
T1 魔法森林
原题:P9504
题意概述:有一个 nn 个点 mm 条边的无向简单连通图,有两个属性 AABB,每经过一条边 AA 就少 11,每条边有边权 ww,若你在经过某条边时,属性 AA 的值为 kk,则你的属性 BB 值会掉 wk\dfrac{w}{k},若你需要从 sstt,求最少 BB 属性的个数,n2×104n \le 2 \times 10^4m4×104m \le 4 \times 10^4w100w \le 100
25pts:
Subtask 3,w1w \le 1,答案最多为 11,如果到终点的边有 w=0w=0 的,就为 00,否则为 11
50pts:
爆搜即可。
75pts:
倒着搜。
100pts:
倒着搜,不超过 ww 条边之后代价为 00,注意到 ww 很小(100\le 100),考虑 DP,fu,if_{u,i} 表示倒着走到 uu,已经走了 ii 条边的最小生命值。所以我们发现这就是分层图最短路,跑一次 Dijkstra,时间复杂度 O(w(n+m)logmw)O(w(n+m) \log mw)
注意到分层路连边每次都是 ii 层到 i+1i+1 层,拓扑序已经做好,所以发现不需要 Dijkstra,是一个 DP,DP转移方程式是:fv,i+1f_{v,i+1}=min\min(wu,vw_{u,v}) (fu,i+wu,v)(f_{u,i}+w_{u,v}),时间复杂度 O(w(n+m)O(w(n+m))。
T2 异或
原题:P7335
题意概括:nn 个数,选出 kk 个不交区间 [Li,Ri][L_i,R_i],求这 kk 个区间异或和之和最大值 ,kn3000k \le n \le 3000
5pts 爆搜,O(n2k)O(n^{2k})
25pts: O(n3)O(n^3) dp。
fi,jf_{i,j} 表示前 ii 个数分成 jj 个区间的答案。
加区间:以 ii 结尾,以 ll 开头,ll11iifi,j=fl1,j1+wl,if_{i,j}=f_{l-1,j-1}+w_{l,i}
不加区间:fi,j=fi1,jf_{i,j}=f_{i-1,j}
总时间复杂度 O(n2×k)O(n^2 \times k)
100pts:
区间无用的定义:如果一个区间比另一个区间长,异或和又比另一个区间小。
舍弃后有多少个区间?[i,i][i,i] 一定要。[i1,i][i-1,i] 要的当且仅当 aixorai1>aia_i xor a_{i-1}>a_i,概率为 12\dfrac{1}{2}。又 [i2,i][i-2,i] 要的当且仅当 aixorai1xorai2>a_i xor a_{i-1} xor a_{i-2}> aixorai1a_i xor ai-1aia_i,概率 13\dfrac{1}{3},所以一个区间有用的概率为长度分之1,所以有的个数的期望时 1j1jn=lnn+O(1)\sum{\dfrac{1}{j}(1 \le j \le n)}= \ln n+O(1)
O(n2)O(n^2) 预处理有用区间后在25pts的加区间的时候只考虑有用区间,复杂度从 O(n)O(n) 变成 O(lnn)O(ln n),所以,复杂度变成了 O(n×k×lnn)O(n \times k \times ln n)
T3 小 C 的树 II:
题意:
nn 个节点的树,你可以进行一种操作:把 ii 号节点的子树所有都增加 vv,但需要代价 cic_i,求最小代价使得其点权都不一样且不等于 00n2×105n \le 2 \times 10^5,点权修改后不能超过 2×1052 \times 10^5
10pts10pts
菊花图,答案为 cimaxci\sum c_i - \max{c_i},构造方案即可。
30pts30pts
n18n \le 18 直接爆搜,有几个点,就构造 22 的几次方。
100pts100pts
正解思路:
非常神奇。以根结点为根给每个节点做一个 dfs 序,得到每个叶子节点都代表一个区间 [L,R)[L,R),每次给 LLRR 连边,记 ss 为叶子数量,则构成一张 s+1s+1 个点 的 nn 条边的图,每条边的边权为 cic_i,则答案为这张图的最小生成树。
为什么选最小生成树?我们需要选 ss 条边,假如我们选的一些边构成环,对于某条边而言,环上的一条边都可以被环上其他边的加减表示,相当于被其他边取代了,这条边就是没有用的,就需要直接删去,所以 ss 条边是一颗生成树。
为什么一定要选 ss 个点?我们现在假设一个集合 SS0S0∈S,所有叶子节点 S∈ S,每次的操作就是将一个小集合剥离大集合,所以我们至少需要选择 ss 条边,所以构成一颗生成树。
这样我们就求出了选择的最小生成树。
我们设配对点的编号等于叶子的权值,得出结论,你选择的 ss 个叶子,选择的跳到最近的一个点必须是不相同的。DFS 一遍,每次加上这个节点的权值,并且把上面的节点的权值减去。
dfs(u,add)dfs(u,add) 表示当前进行到 uu 节点,上面已经选了 addadd 的权值,时间复杂度 O(slogs)O(s \log s),是求最小生成树的时间复杂度。
T4 最大子段和:
原题:CF280D
题意概述:
nn 个数,qq 次操作:
1.1.axa_x 改为 vv
2.2. 求出 [L,R][L,R] 选出 kk 个子段的最大和。保证 n,q105n,q \le 10^51k201 \le k \le 20
12pts12pts
纯暴力。
28pts28pts
fi,j,0f_{i,j,0} 表示第 jj 个区间还没锁死。
fi,j,1f_{i,j,1} 表示第 jj 个区间已经锁死了,想在第 i+1i+1 个点再开一个新区间。
状态转移是 O(1)O(1) 的,时间复杂度 O(qnk)O(qnk)
44pts44pts
线段树求区间最大子段和。
时间复杂度 O(nlogn)O(n \log n)
56pts56pts
v,ai<0v,a_i<0,很简单(送分),答案是 00
100pts100pts
注意到 kk 很小,考虑 DP。
以拼完/没拼完设计状态。
只有两边可能没拼完。
设计状态 fi,0/1,0/1f_{i,0/1,0/1},表示选择 ii 个区间,左边选没选完,右边选没选完,状态转移也很简单。
每次 pushup 的复杂度 O(k2)O(k^2),时间复杂度是 O((n+qlogn)k2)O((n+q \log n) k^2),时限有 44 秒,卡常后可以过。
注意到这个东西合并是有凸性的,这样可以将时间复杂度降到 O(k)O(k),时间复杂度 O((n+qlogn)k)O((n+q \log n)k)

评论

0 条评论,欢迎与作者交流。

正在加载评论...