CF1479D Odd Mineral Resource 题解

本题有两种算法,一种是 log ⁡ n \log n logn 级别算法,一种是 n \sqrt{n} n 级别算法,这里只讲根号算法。

这道题就是一个树上数颜色问题,只是颜色被限定在一个区间。

如果你做过 P4396 [AHOI2013]作业,我相信你能一眼看出这道题的做法。

数颜色问题的根号算法做法一般是莫队,而这道题是树上莫队。

如果你没学过莫队,看一下我的算法总结

如果你没学过树上莫队但是学过莫队,可以看我的算法总结,也可以在代码后面看我写的简要描述。

好的下面默认你学会了树上莫队。

那么有一种方法就是我们在树上莫队的时候维护一棵线段树,对于加删操作而言我们在线段树对应位置修改,线段树中维护当前区间是否存在奇数个颜色,查询时直接查即可。

这个做法的复杂度是 O ( q log ⁡ n n + q log ⁡ n ) O(q \log n \sqrt{n}+q \log n) O(qlognn +qlogn) 的,会被 #7 卡 TLE。

发现修改操作复杂度 q log ⁡ n n q \log n \sqrt{n} qlognn 远大于查询操作复杂度 q log ⁡ n q \log n qlogn,因此我们需要考虑平衡一下这两者。

因此我们可以采用值域分块。

如果你没学过值域分块,建议先去学一下分块(我的算法总结),然后类比值域线段树,值域分块就是在值域上分块。

值域分块有一个好处是 O ( 1 ) O(1) O(1) 修改 O ( n ) O(\sqrt{n}) O(n ) 查询,而这可以平衡复杂度,使得修改操作和查询操作都是 O ( q n ) O(q\sqrt{n}) O(qn )

需要注意的是如果块长不当,可能会被 #7 卡掉,这里建议调成理论最优块长 2 n m \dfrac{2n}{\sqrt{m}} m 2n 2 n 2n 2n 是因为欧拉序长为 2 n 2n 2n),如果还不过就在这附近调块长。

Code:GitHub CodeBase-of-Plozia CF1479D Odd Mineral Resource.cpp

树上莫队简介:

做树上莫队,你需要知道欧拉序。

欧拉序就是 DFS 序的升级版,在每一次遍历到这个节点的时候记录一次,离开这个节点的时候再记录一次。

一般采用 f i r x fir_{x} firx 表示 x x x 在欧拉序中第一个出现的位置, l a s x las_{x} lasx 表示 x x x 在欧拉序中第二个(最后一个)出现的位置。

当一个询问询问路径 x → y x \to y xy 的时候,如果 x , y x,y x,y 在一条链上,询问的区间就是 [ f i r x , f i r y ] [fir_x,fir_y] [firx,firy],否则就是 [ l a s x , f i r y ] [las_x,fir_y] [lasx,firy],具体询问区间可以使用 LCA 判断。

需要注意的是当询问 [ l a s x , f i r y ] [las_x,fir_y] [lasx,firy] 的时候,不能忘记计算他们 LCA 的贡献。

由于一个点在欧拉序中会出现两次,因此树上莫队的修改采用奇增偶删原则,即若这个点是奇数次被修改就增加,偶数次被修改就减少。

写的有点少大致看看吧qwq

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值