权值线段树&线段树合并
更新地址:传送门
---
权值线段树
所谓权值线段树,就是一种维护值而非下标的线段树,我个人倾向于称呼它为值域线段树。
举个栗子:对于一个给定的数组,普通线段树可以维护某个子数组中数的和,而权值线段树可以维护某个区间内数组元素出现的次数。
在实现上,由于值域范围通常较大,权值线段树会采用离散化或动态开点的策略优化空间。
更新操作:
更新的时候,我们向线段树中插入一个值v,那么所有包含v的区间值都需要+1。(每个节点维护对应区间中出现了多少个数)
int update (long long v,long long l,long long r,int pos) { // 插入v,当前区间为[l,r]。
if (!pos) pos=++tot_node;
// 如果该节点不存在,则新建节点。
if (l<=v&&v<=r) {
// 如果当前区间包含插入值。
tree[pos].val++;
// 出现次数+1。
if (l==r) return pos;
// 如果递归到叶子节点,退出。
}
long long mid=(l+r)>>;
if (v<=mid) tree[pos].ls=update(v,l,mid,tree[pos].ls);
else tree[pos].rs=update(v,mid+,r,tree[pos].rs);
// 判断插入值是在当前区间的哪一半。
pushup(pos);
// 回溯。
return pos;
}
查询操作:
查询操作类似二叉树。
1 long long query (long long l,long long r,long long L,long long R,int pos) { // 查询区间[L,R]中数字的数量,当前区间为[l,r]。
2 if (!pos) return 0;
3 // 如果该节点不存在,必然没有到达过。
4 if (L<=l&&r<=R) {
5 // 如果当前区间属于查询区间。
6 return tree[pos].val;
7 // 直接返回区间中数字的数量。
8 }
9 long long mid=(l+r)>>1,ans=0;
10 if (L<=mid) ans+=query(l,mid,L,R,tree[pos].ls);
11 if (mid<R) ans+=query(mid+1,r,L,R,tree[pos].rs);
12 // 统计区间和。
13 return ans;
14 }
练习题:
作为练习模板,可以考虑逆序对。大体思路是每次查询a[i]+1~n的元素个数。
线段树合并
所谓线段树合并,就是通过将合并两颗线段树获得信息,其正确性由线段树的稳定结构保证。
线段树合并通常是一个自底向上的过程,在深搜的途中将子节点的树合并到父节点上,从而实现对父节点值的统计。
线段树合并的复杂度是$nlogn$,比启发式合并少一个$logn$。
不难发现,如果按照线段树合并的原始思想直接在每一个需要遍历的节点上都单独建立一个线段树肯定会爆空间。在这里可以使用被称为“回收内存”的方法:由于在合并之后子节点的信息已经归入父节点,所以子节点没有用处,那么可以将其所有节点回收丢入一个内存池,往后更新的时候可以从内存池里取节点而非新建节点。
回收内存:
inline int newId () {
if (pool_top) return mempool[pool_top--];
return ++tot_node;
}
inline void killId (int &x) {
mempool[++pool_top]=x;
tree[x].ls=tree[x].rs=tree[x].val=;
x=;
}
合并操作:
合并操作与左偏树的合并有一点像,就是递归合并每一个节点。
int merge (int l,int r,int x,int y) {
if (!x||!y) return x+y;
int now=newId(),mid=(l+r)>>;
if (l==r) {
tree[now].val=tree[x].val+tree[y].val;
} else {
tree[now].ls=merge(l,mid,tree[x].ls,tree[y].ls);
tree[now].rs=merge(mid+,r,tree[x].rs,tree[y].rs);
tree[now].val=tree[tree[now].ls].val+tree[tree[now].rs].val;
}
killId(x),killId(y);
return now;
}
练习题:
可以考虑做一下Tree Rotation,大致题意是给一棵二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少。
由于左右儿子的交换不会影响更上层的值,所以在每次合并的时候直接统计即可。
权值线段树&线段树合并的更多相关文章
- HihoCoder1576 子树中的最小权值( dfs序 +线段树 || 树剖)
给定一棵N个节点的树,编号1~N.其中1号节点是根,并且第i个节点的权值是Vi. 针对这棵树,小Hi会询问小Ho一系列问题.每次小Hi会指定一个节点x,询问小Ho以x为根的子树中,最小的权值是多少.为 ...
- 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树
[BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...
- BZOJ4771七彩树——可持久化线段树+set+树链的并+LCA
给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节 点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义dept ...
- BZOJ3110 K大数查询 【线段树 + 整体二分 或 树套树(非正解)】
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- 97: cf 983E 倍增+树套树
$des$一棵 $n$ 个点的树,树上有 $m$ 条双向的公交线路,每条公交线路都在两个节点之间沿最短路径往返.$q$ 次询问从一个点要到达另一个点,在只坐公交的情况下,至少需要坐几辆公交车:或者判断 ...
- B20J_2733_[HNOI2012]永无乡_权值线段树合并
B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...
- 【bzoj1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+权值线段树合并
题目描述 求一张图的严格次小生成树的边权和,保证存在. 输入 第一行包含两个整数N 和M,表示无向图的点数与边数. 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z ...
- [bzoj 2733]启发式合并权值线段树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 平衡树待学习.从一个博客学到了合并权值线段树的姿势:http://blog.csdn ...
- 【bzoj4719】[Noip2016]天天爱跑步 权值线段树合并
题目描述 给出一棵n个点的树,以及m次操作,每次操作从起点向终点以每秒一条边的速度移动(初始时刻为0),最后对于每个点询问有多少次操作在经过该点的时刻为某值. 输入 第一行有两个整数N和M .其中N代 ...
- 【bzoj2212】[Poi2011]Tree Rotations 权值线段树合并
原文地址:http://www.cnblogs.com/GXZlegend/p/6826614.html 题目描述 Byteasar the gardener is growing a rare tr ...
随机推荐
- Git使用SSH提交代码到server出现 permission denied (publickey).
在GitBush中向已经存在的Repository提交README.md改动. 命令例如以下: touch README.md git init git add README.md git commi ...
- URAL 1601. AntiCAPS (strings)
1601. AntiCAPS Time limit: 0.5 second Memory limit: 64 MB The blonde Angela has a new whim: internet ...
- css中的绝对定位和相对定位(详解,总结)
css中的绝对定位和相对定位(详解,总结) 总结: 设置绝对定位或者相对定位后都从文档中浮起来了,区别是相对定位还占着原来的位置,绝对定位不占着原来的位置,可以种z-index来改变元素的浮动的堆叠次 ...
- ES transport client批量导入
从bulk.txt文件中按行读取,然后bulk导入.首先通过调用client.prepareBulk()实例化一个BulkRequestBuilder对象,调用BulkRequestBuilder对象 ...
- POJ 3264 Balanced Lineup (线段树)
Balanced Lineup For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the s ...
- DCloud-MUI:AJAX
ylbtech-DCloud-MUI:AJAX 1.返回顶部 1. 2. 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 1. http://dev.dcloud.net.cn ...
- openSTack manual 整合调优
- SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)
SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...
- 安装DotnetCore-Vue项目模板
dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
- python 字符编码的两种方式写法:# coding=utf-8和# -*- coding:utf-8 -*-
python运行文件是总会出现乱码问题,为了解决这个问题,在文件开头加上: # coding=utf-8 或者 # -*- coding:utf-8 -*- # coding=<encodin ...