线段树
时间:2019-06-12
本文章向大家介绍线段树,主要包括线段树使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
线段树
#include<cstdio>
const int MAXNC = 10100;
int a[MAXNC], tree[MAXNC << 2];
int x, y, n, m;
void built(int l, int r, int o) {
if(l == r) {
tree[o] = a[l];
return;
}
int m =(r - l >> 1) + l;
built(l, m, o << 1);
built(m + 1, r, o << 1 | 1);
tree[o] = tree[o << 1] + tree[o << 1 | 1];
return;
}
void update(int l, int r, int o) {
if(l == r) {
a[x] = y;
tree[o] = a[x];
return;
}
int m = (r - l >> 1) + l;
if(x <= m) update(l, m, o << 1);
else update(m + 1, r, o << 1 | 1);
tree[o] = tree[o << 1] + tree[o << 1 | 1];
}
int query(int l, int r, int o) {
int m = (r - l >> 1) + l, ans = 0;
if(l >= x && r <= y) return tree[o];
if(m >= x) ans += query(l, m, o << 1);
if(y > m) ans += query(m + 1, r, o << 1 | 1);
return ans;
}
int main() {
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
built(1, n, 1);
for(int i = 1; i <= m; i++) {
scanf("%d", &x);
if(x == 1) { // 单点修改
scanf("%d %d", &x, &y); // a[x] = y
update(1, n, 1);
}
else if(x == 2) { // 区间查询
scanf("%d %d", &x, &y);
printf("%d\n", query(1, n, 1));
}
}
return 0;
}
/*
5 5
1 2 3 4 5
2 1 3
2 1 5
1 1 5
2 1 5
2 1 4
*/
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAX 10000
#define INF 2147000047
int n,m;
int minv[MAX],sumv[MAX];//附加信息
int ql, qr;//查询区间
//查询[qr, ql]中的最小值
int query_min(int o, int L, int R) {
int M = (L + R) >> 1, ans = INF;
if(ql <= L && R <= qr) return minv[o]; //递归出口(当前节点完全在查询区间内)
if(ql <= M) ans = min(ans, query_min(o*2, L, M) );//往左走(查询区间在左儿子节点中有元素)
if(M < qr) ans = min(ans, query_min(o*2+1, M+1, R) );//往右走(同理
return ans;
}
//查询[qr, ql]元素和
int query_sum(int o, int L, int R) {
int M = (L + R) >> 1 , ans = 0;
if(ql <= L && R <= qr) return sumv[o];//出口
if(ql <= M) ans += query_sum(o*2, L, M);
if(qr > M) ans += query_sum(o*2+1, M+1, R);
return ans;
}
int p,v;//修改A[p] = v
void update(int o, int L, int R) {
int M = (L + R) >> 1;
if(L == R) {
minv[o] = v;
//....
}
else {// L < R
//先递归更新左子树 或 右子树
if(p <= M) update(o*2, L, M); else update(o*2+1, M+1, R);
//然后计算本节点的附加值
minv[o] = min(minv[o*2], minv[o*2+1]);
}
}
int mian() {
scanf("%d%d",&n,&m);
for(p = 1; p <= n; p++) {
scanf("%d", &v);
update(1, 1, n);//建树
}
}
原文地址:https://www.cnblogs.com/tyner/p/11011244.html
- 由浅入深表达式树(完结篇)重磅打造 Linq To 博客园
- 算法之逆序对
- Windows平台分布式架构实践 - 负载均衡
- Web Service初探
- async & await 的前世今生(Updated)
- MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN
- Spring @Transactional踩坑记
- jvm运行时环境属性一览
- bootstrap + requireJS+ director+ knockout + web API = 一个时髦的单页程序
- C#集合类型大盘点
- 将spring源码导入到eclipse中
- 将struts源码导入eclipse
- 初探领域驱动设计(1)为复杂业务而生
- 最大公约数的算法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法