CF1375H Set Merging

这篇题解写的真是太好辣!
虽然实际上是我自己脑补的

看题解之前先看清楚题意。。原序列是个排列,不是有序的,要把 [ l , r ] [l,r] [l,r] 位置的集合合并出来,合并要保证值域有序。

对值域分块,然后将每一块中位置在 [ l , r ] [l,r] [l,r] 的段提取出来,依次合并。这一步合并次数是 n q B \frac {nq}B Bnq 的。

然后考虑怎么把值域块内的每个位置连续段合并出来,因为位置连续段的值域并不一定连续,再次对值域分治,先合并出值域在 [ L , M ] , [ M + 1 , R ] [L,M],[M+1,R] [L,M],[M+1,R] 的位置连续段,然后归并得到 [ L , R ] [L,R] [L,R] 的所有位置。枚举位置连续段的左右端点,将该段值域在 [ L , M ] [L,M] [L,M] 的段提取出来,与值域在 [ M + 1 , R ] [M+1,R] [M+1,R] 的段合并。
合并的次数是 f ( V ) = V 2 2 + 2 f ( V 2 ) = V 2 f(V)=\frac {V^2}2+2f(\frac V2)=V^2 f(V)=2V2+2f(2V)=V2 的,每块大小 B B B,总次数就是 B 2 ∗ n B = n B B^2*\frac nB=nB B2Bn=nB 的。

B = q B=\sqrt q B=q 就可以做到 2 n q 2n\sqrt q 2nq

看代码的时候发现 STL 的 merge 函数居然有归并的功能,i了i了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值