这道题的正解是线段树维护可合并区间状态,但我们用朴素模拟合并也能在考试时拿到一定的分数。每次区间查询从 l 到 r 依次合并,单点更新直接改数组;B、Q 较小时完全够用,大数据会超时。
#code-switcher
import math
在 Transformer 的 Attention 计算中,为降低长序列的内存开销,常采用 FlashAttention 分块流式计算。每个序列块维护局部状态三元组 (mx,wd,sv),其中:
该块的注意力结果为 attn=sv/wd。
相邻两块状态 A=(mxA,wdA,svA) 与 B=(mxB,wdB,svB) 按顺序合并为 C=(mxC,wdC,svC):
mxCwdCsvC=max(mxA,mxB)=wdA⋅emxA−mxC+wdB⋅emxB−mxC=svA⋅emxA−mxC+svB⋅emxB−mxC合并运算满足结合律,可按任意括号顺序得到相同结果。
现给定按顺序排列的 B 个块,第 i 块初始状态为 (mxi,wdi,svi)。需处理 Q 次操作:
第一行:两个整数 B、Q,分别表示块数与操作数。
接下来 B 行:每行三个实数 mxi wdi svi,表示第 i 块的初始状态(1≤i≤B)。
接下来 Q 行:每行描述一次操作:
1 i mx wd sv:单点更新第 i 块,无输出;2 l r:查询区间 [l,r] 合并后的注意力结果。数据范围:
提示:涉及指数运算,请使用双精度浮点(double / float),指数函数用标准库 exp()。
对每个区间查询操作,输出合并后的注意力结果,保留小数点后 6 位。
输入
4 6
0.0 2.0 4.0
2.0 1.5 9.0
1.0 3.0 6.0
4.0 2.0 8.0
2 1 4
2 2 2
1 3 0.0 1.0 20.0
2 1 3
2 3 4
2 4 4
输出
4.014241
6.000000
6.426028
4.145195
4.000000
说明
初始四块状态为 (0,2,4)、(2,1.5,9)、(1,3,6)、(4,2,8)。
查询 [1,4]:四块依次合并,mx 取到 4.0,经指数重缩放后 attn≈4.014241。
查询 [2,2]:单块,9.0/1.5=6.000000。
将块 3 更新为 (0,1,20) 后,查询 [1,3] 得 attn≈6.426028;查询 [3,4] 得 4.145195;查询 [4,4] 得 8.0/2.0=4.000000。
输入
2 3
1.0 2.0 8.0
1.0 2.0 12.0
2 1 2
2 1 1
2 2 2
输出
5.000000
4.000000
6.000000
说明
两块 mx 均为 1.0,合并时缩放因子相同,[1,2] 等价于权重与值直接相加:attn=(8+12)/(2+2)=5。单查块 1 得 4,单查块 2 得 6。
By signing up a CodeFun2000 universal account, you can submit code and join discussions in all online judging services provided by us.