归并树 学习笔记

归并树

Problem

给定一个长为 n n n 的数组。
q q q 次查询,每次查询包括一个区间,需要回答关于区间元素排序的问题

示例 :区间第 k k k 大值,link

数据强制在线 , n , q ≤ 1 0 5 n,q \leq 10^5 n,q≤105。

Algorithm description

Method

归并树顾名思义,就是逐个归并的树。

每个节点是其子节点代表的数组归并后的数组,这样能使任意一个节点有序。

也就是说,建树时,每个节点代表了 a l a_l al 至 a r a_r ar 归并后的数组

我们在实现时,为了节约空间,可以开 dep × n \text{dep}\times n dep×n 的归并数组,每一层为下一层归并的结果。

这种树的优势在于,能够像线段树一样 O ( log ⁡ n ) O(\log n) O(logn) 统计出可以叠加的排序的结果

Code

以 POJ2104 (见上文)为例,可以二分答案再查找。

cpp 复制代码
int sorted[25][2000001], a[200001];

void build(int l, int r, int dep){
    if(l == r){
        sorted[dep][l] = a[l]; return;
    }
    int mid = l + r >> 1;
    build(l, mid, dep + 1);
    build(mid + 1, r, dep + 1);
    // Merging.
    int pos = l, pos1 = mid + 1, tot = l;
    while(pos <= mid && pos1 <= r){
        if(sorted[dep + 1][pos] < sorted[dep + 1][pos1])
            sorted[dep][tot] = sorted[dep + 1][pos], pos++, tot++;
        else
            sorted[dep][tot] = sorted[dep + 1][pos1], pos1++, tot++;
    }
    while(pos <= mid) sorted[dep][tot] = sorted[dep + 1][pos], pos++, tot++;
    while(pos1 <= r) sorted[dep][tot] = sorted[dep + 1][pos1], pos1++, tot++;
}
int query(int l, int r, int x, int y, int tar, int dep){
    if(x <= l && r <= y){
    	// Here it is possible to calculate the sum thanks to the merging above.
        return upper_bound(sorted[dep] + l, sorted[dep] + r + 1, tar) - sorted[dep] - l;
    }
    int mid = l + r >> 1, ans = 0;
    if(x <= mid) ans += query(l, mid, x, y, tar, dep + 1);
    if(mid < y) ans += query(mid + 1, r, x, y, tar, dep + 1);
    return ans;
}
相关推荐
WindSearcher23 分钟前
大模型微调相关知识
后端·算法
取酒鱼食--【余九】33 分钟前
rl_sar实现sim2real的整体思路
人工智能·笔记·算法·rl_sar
Magnum Lehar2 小时前
vulkan游戏引擎test_manager实现
java·算法·游戏引擎
水蓝烟雨2 小时前
[面试精选] 0094. 二叉树的中序遍历
算法·面试精选
超闻逸事3 小时前
【题解】[UTPC2024] C.Card Deck
c++·算法
暴力求解3 小时前
C++类和对象(上)
开发语言·c++·算法
JKHaaa3 小时前
几种简单的排序算法(C语言)
c语言·算法·排序算法
让我们一起加油好吗3 小时前
【基础算法】枚举(普通枚举、二进制枚举)
开发语言·c++·算法·二进制·枚举·位运算
FogLetter3 小时前
微信红包算法揭秘:从随机性到产品思维的完美结合
算法
BUG收容所所长4 小时前
二分查找的「左右为难」:如何优雅地找到数组中元素的首尾位置
前端·javascript·算法