保证接下来提到的算法都将是在线的。
虽然分了几个算法但其实是一个。
一:
预处理所有区间[p*block+1,q*block]代表的值。
其中:p、q为自然数0、1、……、[n/block]
block在前一篇文章中提到过,最适合取n/sqrt(m)。
这样共记录下m个值,简单分析得平均复杂度n*sqrt(m)。
然后对于每个询问[L,R],找到距离它最近的已记录点。
已知所需步数不超过block=n/sqrt(m),合计时间复杂度n*sqrt(m)。
Over.
二:
上述算法所需额外空间是O(m)的。
我们假设空间足够——事实上,最好有O(n*sqrt(m))(没有的话O(n*sqrt(n))也行啊,再小点也行啊……)
那么我们不妨记录下区间[p*block+1,1..n]的所有值。
对于任意询问[L,R]向左/右找到一个已记录值。
(我觉得)我们能拿它干很多事。
三:
题外话。
面对已输入的数据或题目隐藏信息,假如区间询问密度不同,更好的选点方法。
算给自己的思考题好了。
……NOIP挂成狗。
……一定要出题把无脑分块卡掉!
时间: 2024-10-18 20:55:33