多校 A 层冲刺 NOIP2024 模拟赛 07

多校A层冲刺NOIP2024模拟赛07

T1 限速(speed)

签到题

求一棵树的边的总贡献最小,考虑最小生成树。但此时未考虑最大值恰好为 k 的限制,考虑分讨。若最终的最小生成树中包含了一条原边权大于等与 k 的则不用处理。若未包含则答案为 \(\min\{|w_i-k|\}\),证明考虑最终状态已经构成一棵树可以通过加一条不属于集合的边去除一条不属于集合的边去满足限制。

T2 酒鬼(drunkard)

签到题

时间的限制显然会更大,考虑按时间线维护这个过程,由于时间比较大,可以使用 \(set\) 容器维护。

注意到一个 \(p_i≠1\) 的信息只用关心时间线上的前驱后继,即维护 \(p_i+q_i\) 的奇偶性一致。

但由于出发点为 \(1\),所以当 \(p=1\) 的前缀(即到某一个时间之前信息全是在 \(1\) 号点的)发生奇偶冲突时,出发时间应至少在冲突之后,动态维护这个前缀即可。

对于 \(min\) 而言只需若前缀冲突则需大于前缀冲突时间,若不存在前缀冲突则答案为 \(1/0\) (第一个的点的奇偶应与出发时间的奇偶一致)。

对于 \(max\) 而言显然在前缀后出发最优,如果全为 \(1\) 则输出 \(inf\),否则去除前缀 \(1\) 同上处理即可。

Cornercase 比较多,代码实现比较平凡。

T3 距离(distance)

推式子,距离,线段树合并

注意到 父亲的答案=其儿子的答案+儿子之间的贡献。

自然想到启发式合并去计算儿子之间的贡献,但是直接做(大力分讨+树套树之类的)有 \(3\)\(log\)\(5e5\) 的数据显然不可能

考虑优化式子

\[\begin{aligned} 原式&=\min\{|a_x-a_y|,|b_x-b_y|\} \\ &=|a_x-a_y|+|b_x-b_y|-\max\{|a_x-a_y|,|b_x-b_y|\}\quad(\min,\max 容斥) \\ &=|a_x-a_y|+|b_x-b_y|-\left(\left|\frac{a_x+b_x}{2}-\frac{a_y+b_y}{2}\right|+\left|\frac{a_x-b_x}{2}-\frac{a_y-b_y}{2}\right|\right) \\ &(将a,b两值看作坐标,原带\max 的式子即切比雪夫距离,转化为曼哈顿距离去掉\max ) \\ &=|a_x-a_y|+|b_x-b_y|-\frac{1}{2}|(a_x+b_x)-(a_y+b_y)|-\frac{1}{2}|(a_x-b_x)-(a_y-b_y)| \end{aligned} \]

关于距离

线段树分别维护这四个绝对值的部分,此时就能优化掉一只 \(log\),但不是很优秀。

注意到在插入一些值时一些部分的贡献会被计算多次,因而想到线段树合并

具体的

\[\begin{aligned} ans[l,r]&=ans[l,mid]+ans[mid+1,r] \\ &+sum[mid+1,r]\times cnt[l,mid]-sum[l,mid]\times cnt[mid+1,r] \end{aligned} \]

维护 \(3\) 个数组,直接合并最终线段树根的答案即这个点的答案。

这样就把时间复杂度降到的 \(O(nlogn)\),非常优秀。

在代码实现上计算四个绝对值是相同的过程,可以处理出每个绝对值对应数组,做四遍相同的操作把数组传进去乘上个系数统计入答案即可。

T4 团队选拔(selection)

特殊性质,最大公约数,DP,单调栈,优化DP,差分,计数题

  • 一个关于区间 \(gcd\) 的重要结论:当以一个点为右端点时,左端点向左移动,区间 \(gcd\) 只会变化 \(logV\) 次,证明考虑每次变化 \(V\) 会至少失去一个质数因子,则至少减半。

本题由于得计算每个点被包含的方案,所以得想一种好的统计答案的方法。正难则反,考虑用总方案减去不包含的方案,而不包含的方案是可以通过左右拼接去统计的,具体的可以枚举所有合法 \(gcd\)(由结论得知共有 \(O(nlogV)\) 个 )然后对所有点统计一次,设 \(f_i\) 表示考虑前 \(i\) 个,所有区间 \(gcd\) 已定,同理有 \(g_i\) 为后缀的方案数,对于已定 \(gcd\) 不包含 \(i\) 的方案数为 \((f_{i-1}+1)(g_{i+1}+1)-1\)

考虑如何求出 \(f\) 数组( \(g\) 数组同理 )。若不存在以 \(i\) 为右端点,区间 \(gcd\) 为枚举值的左端点,则 \(f_{i}=f_{i-1}\);若存在,则合法的左端点一定构成一个区间设为 \([l,r]\),则 \(f_{i}=f_{i-1}+\sum_{k=l}^r(f_{k-1}+1)\)

上述的区间 \([l,r]\) 的个数只会有 \(O(nlogV)\) 个,考虑结论即可计算。可以使用一个单调栈提前预处理出来以便于后面优化 \(DP\) 。具体的栈中维护一些三元组形如 \((l,r,v)\) 表示当前枚举到的右端点,左端点在 \([l,r]\) 的范围内的区间 \(gcd\)\(v\),其中三元组按 \(v\) 的大小排序( \(v\) 严格单调,这样区间位置也是单调的且不交),每一次继承(即枚举到下一个右端点时)会给所有 \(v\) 做一次 \(gcd\),这个时候需要去重合并,去重合并后栈中的三元组就是上述区间 \([l,r]\)
时间复杂度为 \(O(nlog^2V)\)

现在 DP 部分的时间复杂度太高了,考虑优化。两种转移可以分别用线段树区间赋值、区间求和优化,而转移次数是与上述区间个数挂钩的,即会转移 \(O(nlogV)\) 次,所以 DP 部分的时间复杂度为 \(O(nlogVlogn)\)

考虑统计答案,由于此时枚举的合法 \(gcd\) 比较多,不可能每个点单独去计算一次。注意到对给定 \(gcd\)\(f\) 数组的值和 \(g\) 数组的值会构成一段段值相同的区间,可以用差分优化统计答案。具体的计算 \(f,g\) 数组所有不同区间的交,计算值即可。

总时间复杂度为 \(O(nlog^2n)\)

p

posted @ 2024-10-16 09:51  Qyun  阅读(118)  评论(0编辑  收藏  举报