线段树 (模板)
时间:2020-04-14
本文章向大家介绍线段树 (模板),主要包括线段树 (模板)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
功能
用\(log_2n\)时间复杂度对区间进行加减乘除求和等等操作的数据结构。
实现
主要参考的是oi_wiki教程。
记录一下板子(即HDU1166 - 敌兵布阵的代码)
//L,R均代表待处理的区间。
//lef,rig均代表范围。
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const ll maxn = 50001;
ll sum[maxn << 2];
ll lazy[maxn << 2];
void pushup(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void pushdown(int rt, int len) {
if(lazy[rt]) {
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
sum[rt << 1] += lazy[rt << 1] * (len - (len >> 1));
sum[rt << 1 | 1] += lazy[rt << 1 | 1] * (len >> 1);
lazy[rt] = 0;
}
}
void update(int L, int R, int lef, int rig, int rt, ll val) {
if(lef >= L && rig <= R) {
sum[rt] += val * (rig - lef + 1);
lazy[rt] += val;
return ;
}
pushdown(rt, rig - lef + 1);
int mid = (lef + rig) / 2;
if(L <= mid) update(L, R, lef, mid, rt << 1, val);
if(R > mid) update(L, R, mid + 1, rig, rt << 1 | 1, val);
pushup(rt);
}
void build(int lef, int rig, int rt) {
if(lef > rig) return ;
lazy[rt] = 0;
if(lef == rig) {
ll tmp;
scanf("%lld", &tmp);
sum[rt] = tmp;
return ;
}
int mid = (lef + rig) / 2;
build(lef, mid, rt << 1);
build(mid + 1, rig, rt << 1 | 1);
pushup(rt);
}
ll query(int L, int R, int lef, int rig, int rt) {
if(lef >= L && rig <= R) return sum[rt];
pushdown(rt, rig - lef + 1);
int mid = (lef + rig) / 2;
ll res = 0;
if(L <= mid) res += query(L, R, lef, mid, rt << 1);
if(R > mid) res += query(L, R, mid + 1, rig, rt << 1 | 1);
return res;
}
int main() {
int T = 0;
char q[10];
scanf("%d", &T);
for(int cases = 1; cases <= T; cases++) {
printf("Case %d:\n", cases);
int n;
scanf("%d", &n);
build(1, n, 1);
while(1) {
scanf("%s", q);
if(!strcmp(q, "Add")) {
int pos;
ll val;
scanf("%d%lld", &pos, &val);
update(pos, pos, 1, n, 1, val);
}
else if(!strcmp(q, "Sub")) {
int pos;
ll val;
scanf("%d%lld", &pos, &val);
update(pos, pos, 1, n, 1, -val);
}
else if(!strcmp(q, "Query")) {
int L, R;
scanf("%d%d", &L, &R);
printf("%lld\n", query(L, R, 1, n, 1));
}
else if(!strcmp(q, "End")) break;
}
}
}
原文地址:https://www.cnblogs.com/limil/p/12698239.html
- Golang Template 简明笔记
- hotspare的copyback(r7笔记第30天)
- Spring-AOP
- DBA和开发同事的一些代沟(三)(r7笔记第29天)
- 简单易学的机器学习算法——非线性支持向量机
- 一条关于swap争用的报警邮件分析(一)(r7笔记第28天)
- Spring-IOC(2)
- Python3 pandas read_csv 读取txt文件报错:IOError: Initializing from file failed
- dataguard添加临时数据文件的bug(r7笔记第27天)
- 简单易学的机器学习算法——线性支持向量机
- Java设计模式-模板方式模式
- 由一条create语句的问题对比mysql和oracle中的date差别 (r7笔记第26天)
- Java设计模式-命令模式
- 关于执行计划中的%CPU的含义 (r7笔记第25天)
- 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 数组属性和方法