专栏文章

SOl P11728(KTT)

P11728题解参与者 2已保存评论 1

文章操作

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

当前评论
1 条
当前快照
1 份
快照标识符
@mipkfm1m
此快照首次捕获于
2025/12/03 13:27
3 个月前
此快照最后确认于
2025/12/03 13:27
3 个月前
查看原文
KTT 做法。这里的变量可能和原题有一定不同。
以下令第 ii 个波特当前的移动速度为 kik_i,当前时刻的位置为 bib_i。初始 ki=0,bi=aik_i=0,b_i=a_i
首先离原点最远的显然就是 bib_i 最大或者 bib_i 最小的,这里只介绍 bib_i 最大的情况,bib_i 最小的情况只需要把初始位置和操作取相反数再求最大即可。
考虑第 pp 次操作和第 p1p-1 次操作之间的 Δt=tptp1\Delta t=t_p-t_{p-1} 秒中发生了什么,对于第 ii 个波特,显然是以 kik_i 的速度匀速移动了 Δt\Delta t 秒,有 bibi+kiΔtb_i\gets b_i+k_i\cdot \Delta t,那就是在每次操作之前,所有 bib_i 都增加 kiΔtk_i\cdot \Delta t
现在需要支持以下三种操作:
  • 给定 Δt\Delta t1in,bibi+kiΔt\forall 1\le i\le n,b_i\gets b_i+k_i\cdot \Delta t,即全局修改 bib_i
  • 给定 pos,vpos,vkposvk_{pos}\gets v,即 command\tt command 操作。
  • maxbi\max b_i,即 query\tt query 操作。
然后这个 kkbb 可以看成一次函数,第一个操作就是所有一次函数左移 Δt\Delta t 个单位,第二个操作就是修改其中一个一次函数的斜率,这个很像 KTT 的形式。
考虑用 KTT 做,每个节点维护三个值:maxk,maxb,w\max_k,\max_b,wmaxk\max_kmaxb\max_b 表示当前 bb 值最大(零点时函数值最大)的一次函数的 kkbbww 就是阈值,即子树内的一次函数再左移 ww 单位之后 maxk,maxb\max_k,\max_b 会改变,如果 max\max 不会改变则 w=w=\infty,一个叶节点 [i,i][i,i]maxk=ki,maxb=bi,w=\max_k=k_i,\max_b=b_i,w=\infty
对于 maxk,maxb\max_k,\max_b 这两个值,合并两个区间 [l,mid],[mid+1,r][l,mid],[mid+1,r] 是简单的,对于 ww,则有 w[l,r]=min(w[l,mid],w[mid+1,r])w_{[l,r]}=\min(w_{[l,mid]},w_{[mid+1,r]}),同时,如果 [l,mid][l,mid][mid+1,r][mid+1,r] 的函数 f1(x)=max[l,mid],kx+max[l,mid],bf_1(x)=\max_{[l,mid],k}x+\max_{[l,mid],b}f2(x)=max[mid+1,r],kx+max[mid+1,r],bf_2(x)=\max_{[mid+1,r],k}x+\max_{[mid+1,r],b}x0x\ge0 有交点 (px,py)(p_x,p_y),那么 max[l,r],k,max[l,r],b\max_{[l,r],k},\max_{[l,r],b} 肯定会在 pxp_x 处(或者前面)发生改变,因此还有 w[l,r]min(w[l,r],px)w_{[l,r]}\gets \min(w_{[l,r]},p_x)
对于所有 bib_i 都增加 kiΔtk_i\cdot \Delta t 这个操作(全体左移 tt 格),维护懒标记 lazy[l,r]lazy_{[l,r]} 表示 [l,r][l,r] 的子树中函数需要左移 lazy[l,r]lazy_{[l,r]} 格。修改一个节点时,如果需要左移 pp 格,则 maxbkip\max_b\gets k_i\cdot p,同时 wwpw\gets w-p,然后懒标记也同时修改一下就行了,在 command\tt command 时再下传。然后对于全体修改,如果 Δt<w[1,n]\Delta t<w_{[1,n]} 就修改节点 [1,n][1,n] 就可以,否则就重构子树,就是递归更新左右子树,令当前节点为 [l,r][l,r],如果 lazy[l,r]+Δtlazy_{[l,r]}+\Delta t 小于子节点的 ww 就继续递归更新,否则直接修改子节点并打上懒标记,然后 pushup。
pushdown 的时候应该是不用判是否超过阈值的,因为如果 Δt<w[1,n]\Delta t<w_{[1,n]} 显然 Δt\Delta t 也小于其子节点的 ww
对于一次 command\tt command 操作,直接找到 [pos,pos][pos,pos],然后逐个 pushup,更新 maxk,maxb,w\max_k,\max_b,w 就行了。
对于 query\tt query 操作,显然 max[1,n],b\max_{[1,n],b} 即为当前时刻答案。
复杂度应该是 O(nlog2n)O(n\log^2 n)O(nlog3n)O(n\log^3 n)?)可以看下 KTT 论文(P52 浅谈函数最值的动态维护)

评论

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

正在加载评论...