问题引入:
给出 n n n个区间 [ l i , r i ] [l_i,r_i] [li,ri],问有多少对区间相交。
基本思路:
按照右端点排序后,从左往右扫,每次先询问再更新;
将右端点的值加
1
1
1,询问当前区间的和;
即单点修改区间查询,可以用树状数组维护。
题型总结:
大概用于:
- 可以离线的区间查询问题
- 枚举右端点,看符合条件的对应点的个数,同时要保证对于每一个右端点来说,合法的对应点的数量不宜超过 n \sqrt n n
- 问题可以转化为点对问题
- 贡献比较好维护
例题:
CF301D.Yaroslav and Divisors
题解
算是比较入门的题,题目难度在于如果快速的求出每个数前面的因子的位置,由于因子最多有
n
\sqrt n
n个,所以每个位置存储的数也最多为
n
\sqrt n
n,整体时间复杂度
O
(
n
n
l
o
g
n
)
O(n\sqrt n logn)
O(nnlogn)
CF220B Little Elephant and Array
题解
难点在于如何利用树状数组的差分原理来进行贡献的增加和消除,要多举例子。还用到了一个小的思维优化。
牛客 小乐乐学数学
题解
需要对每个数进行质因子分解,这是难点一;难点二在于如何消除贡献,细节也比较多。
CF617E XOR and Favorite Number
题解
用这种解法是过不了的。其实离线树状数组跟莫队都是用于离线处理区间问题的,但是如果一个点有
n
\sqrt n
n以上个配对的点时,时间复杂度就会被卡成
O
(
n
2
)
O(n^2)
O(n2),正如本题:如果序列中全为
0
,
1
0,1
0,1,那么对于每一个数,前面都有很多个符合要求的数,遍历一遍进行单点修改显然不可取,只好借助其他数据结构比如莫队啦。
总结:
大体流程就是:
- 将所有询问离线保存,按照右端点排序;(左端点也可)
- 枚举右端点,计算出加入右端点之后前面的数的贡献,同时消除重复的贡献,这里要结合树状数组的差分原理来理解,是题目中不好推的地方;
- 对于每个右端点为当前点的询问,借助区间求和与前缀和求出答案并保存;
- 输出答案;
一些有用的链接
大概是一些进阶题?
反正是从光巨的博客里翻出来的~
完结啦
暂时先这样了吧,明天补一下上面三道题。大概写的时候言语混乱+思绪不清,希望下次看这篇 b l o g blog blog时还能看懂自己写的话。