【学习笔记】[Ynoi2013] 大学
因为学习的其他人的算法,所以叫学习笔记。。。
题意 :
维护序列,支持下列两个操作 :
把区间
[
l
,
r
]
[l,r]
[l,r] 中所有
x
x
x 的倍数除以
x
x
x。
查询区间
[
l
,
r
]
[l,r]
[l,r] 的和。
强制在线。
n ≤ 1 0 5 , a ≤ 5 × 1 0 5 n\leq 10^5,a\leq 5\times 10^5 n≤105,a≤5×105 ,时限 0.5s \texttt{0.5s} 0.5s。
Solution:
伞兵题目 。
求和操作完全就是在误导往线段树上去想 (我太菜了)。
下面做法摘自 command_block
:
显然,只会有 O ( n log a ) O(n\log a) O(nloga) 次生效的除法操作,我们使用树状数组维护区间和,这部分复杂度为 O ( n log a log n ) O(n\log a\log n) O(nlogalogn)。
现在难点在于如何找到应该被除的数。
设 S d S_d Sd 为序列中所有为 d d d 的倍数的数的集合, S 1... a S_{1...a} S1...a 的大小总和是 ∑ d ( a ) = O ( n d ( a ) ) \sum d(a)=O(nd(a)) ∑d(a)=O(nd(a)) 的。而 d ( a ) m a x = 200 d(a)_{max}=200 d(a)max=200 。
当我们区间除 d d d 时,只需要在 S d S_d Sd 中查看。
现在问题变为 : 维护一个序列,支持每次删除一个 区间 内的数。
所以… set 暴力?
可以用并查集 + 链表来维护
链表太恶心了,直接并查集查下一个元素
复杂度 O ( n a + n log a log n ) O(n\sqrt{a}+n\log a\log n) O(na+nlogalogn)。
一些技巧:
Step 1
\text{Step 1}
Step 1
你发现暴力分解约数是
O
(
n
a
)
O(n\sqrt a)
O(na) 而非
O
(
n
a
3
)
O(n\sqrt [3] a)
O(n3a) ,会导致复杂度为
O
(
n
a
+
n
log
n
)
O(n\sqrt a+n\log n)
O(na+nlogn),于是改为筛子预处理因数。
复杂度下降至 O ( a ln a + n a 3 + n log a log n ) O(a\ln a+n\sqrt[3]{a}+n\log a\log n) O(alna+n3a+nlogalogn)。
Step 2
\text{Step 2}
Step 2
预处理因数时,不要用 vector 保存因数,自己写一个邻接表。
甚至发现只有 n < = 1 0 5 n<=10^5 n<=105 个数需要预处理因数,可以大大减小常数。
如果不加上述两条,会得到 98 p t s 98pts 98pts 的好成绩。
Step 3
\text{Step 3}
Step 3
发现每一个位置的下标数组和并查集数组的大小是固定的。
所以保存下标和并查集的时候不需要使用 vector,可以自己开一个内存池,用指针来模拟数组。
这一点是非常重要的。
__EOF__

本文链接:https://www.cnblogs.com/cqbzly/p/17530293.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」