Dynamic Rankings——带修改区间第k大

三种做法:
1.整体二分:

二分mid

考虑小于mid的修改的影响

但是大于mid的修改可能会干掉小于mid的一些值

所以额外把一个修改变成一个值的删除和一个值的添加

这样就相互独立了!

整体二分,树状数组维护即可。

2.树状数组套动态开点线段树

树状数组每个点维护一个线段树,空间O(Nlog^2N)

修改的时候,修改logn个点的线段树,每个点把旧权值--,新权值++。复杂度O(log^2N)

查询的时候,找到[1,l-1],[1,r]两个前缀对应的logn个线段树,然后logn个线段树和logn个线段树差分一下

复杂度O(log^2N)

如果值域过大就离散化。

(不过既然离散化要离线,何不直接整体二分?)

3.分块

万事皆可分块

块内维护原数组(方便修改),排序后的数组

查询,外面二分一个mid,每个块二分小于等于mid第一个数的位置,求出小于等于mid的数的个数。边界暴力处理即可。

修改,直接暴力重构整个块

(也可以每个块维护一个动态开点线段树,不过常数大,而且还不如法二优秀)

O(nsqrt(n)log^2n)由于一个logn比较虚,而且常数很小。所以可过!(惊了)

 

 

加强版:

带修改带插入区间第K大?

正解:替罪羊树套动态开点线段树(log^2N 并不会)

疯狂暴力:分块。还是上面的做法,插入也重构,超过根号必要的时候可以裂解。每次二分到哪个块的哪个位置。还是可以过(惊了)

 

posted @ 2018-12-30 20:10  *Miracle*  阅读(677)  评论(1编辑  收藏  举报