NOIP 模拟赛:2024-10-21

T1:

定义一个序列的权值为相邻两个数较大值再求和。给定一个序列和 \(q\) 次单点修改,每次修改后询问当前序列权值最大的子序列是多少。\(n,q\le 10^5\)

结论 + 模拟题,但是如果不把结论改成方便的形式,可以很难写。

结论:\(\sum max(a_i,a_{i+1},0)\)

T2:

\(n\)根竹竿编号为\(1\sim n\),高度依次是\(h_1, h_2, \dots, h_n\),它们按顺序排成一排,相邻竹竿底端的距离为1。你可以沿着竹竿或地面移动,无法跳跃。
定义两个竹竿之间的距离为一个竹竿顶端到达另一个竹竿顶端的最短移动距离,例如初始时,竹竿\(i\)和竹竿\(j\)距离为\(h_i+ |i-j| + h_j\),即先从竹竿\(i\)顶端到地面上,再在地面从位置\(i\)\(j\),最后移动到竹竿\(j\)顶端。
现在你可以在相邻竹竿之间加一些水平的梯子,一个梯子建在\((i,x)\)\((i+1,x)\),其中\(1\leq i\leq n-1, 0\leq x \leq \min(h_i, h_{i+1})\),即连接了两个竹竿在\(x\)高度的点。你也可以在梯子上移动,从而减少移动的距离。
你想要加一些梯子,使得竹竿两两之间的距离的总和最小。在最小化距离总和的前提下,请问最少加多少个梯子。

\(n\le 10^5\)

容易观察到两根竹竿的最短路径必然是递减走到之间最矮的杆子,然后再一路递增上去。用单调栈之类的容易求出第一问。

然后第二问。考虑分治,每次从当前区间找到最矮的杆子 \(p\),只计算经过 \(p\) 的两根杆子。
\(lm\)\(p\) 左侧最矮的杆子,只考虑 \(lm\) 走到 \(p\) 最短路需新建的桥即可:因为 \(lm\) 左侧到 \(p\) 可以先到 \(lm\)\(lm\) 右侧的因为都比 \(lm\) 高,也可以先下到这些桥上。

\(lm\) 已经可以走到 \(p\) 了(因为可能在更上层的分治建了桥),就不需要新建;否则建桥必然是 \(lm\sim p-1\) 之间都建高度为 \(h[lm]\) 的桥,然后 \(p-1,p\) 之间建高度为 \(h[p]\) 的。
对右侧 \(rm\) 类似处理。

怎么判断当前 \(lm\) 是否可以走到 \(p\)?观察发现,左边、右边新建的桥都是同一高度的(与 \(p\) 相连的不管,因为 \(p\) 不参与下层递归)。因此可以传递两个参数 \(hl,hr\),表示 \(p\)\(p\) 左边已经有高度 \(hl\) 的桥,与右边已经有高度 \(hr\) 的桥了。

T3:

一个数在对一个序列的贡献为它出现次数的 popcnt,一个序列的权值为每种数的贡献求和。求所有总和 \(\le n\) 的序列中权值最大是多少。

把每个数的每个二进制位拆出来作为物品。二分套二分即可。外层二分 "权值为 \(x\) 至少需要多少总和",内层二分 "权值为 \(x\) 至少把多少代价以下的都选了"。

T4:

先考虑排列。容易发现从大到小枚举,决策当前数去左边还是右边所需要经过的比它大的数个数更小。

对于数组,相等的数一起处理了,再一起标记即可。

posted @ 2024-10-29 15:01  FLY_lai  阅读(9)  评论(0编辑  收藏  举报