线段树 ----洛谷p3372
问题描述:
已知一个数列,对数列进行两种操作:1,对数列某个区间中的所有数加d;2,查询数列某区间的区间和
输入:
第一行输入两个整数n和m,分别代表数列中元素个数和对数列的操作次数,第二行输入n个用空格隔开的整数,接下来的m行输入3或4个整数,表示m种操作:
(1)1 L R d:表示对区间[L,R]中的所有数字加d;
(2)2 L R:表示查询并输出[L,R]区间的区间和;
输出:
输出所有操作2的区间和
数据范围:
1<=m,n<=10e5, 数列中元素取值为[-2e63,2e63];
线段树:
使用线段树首先要明确树状数组的叶子节点和子树根节点代表什么,叶子节点自然是代表数组中的元素,由于本题需要解决的都是有关区间的问题,所以子树根节点自然就是区间和,但本题还涉及到区间修改,如果直接再区间中修改,那么每次修改都需要从该修改区间向下传递修改信息直到叶子节点,但查询操作并不是每次修改后都需要查询,显然这将会进行很多不必要的操作增加时间复杂度,有什么可以一劳永逸的呢,最简单直观的方法就是先不修改,直到读取到查询操作的时候再将修改信息传递,对,这就是离线操作和在线操作的区别,也就是线段树中常用的lazy_tag操作,接下来直接看代码:
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const int N = 1e5 + 10;
ll a[N]; //记录数列元素
ll tree[N << 2]; //线段树
ll tag[N << 2];
ll ls(ll p) { return p << 2; }
ll rs(ll p) { return p << 2 | 1; }
void pushup(ll p) {
tree[p] = tree[ls(p)] + tree[rs(p)];
}
//建立线段树
void build(ll p, ll pl, ll pr) {
//调用build(1,1,n);
tag[p] = 0; //由于线段树结构的特性,数组中有很多空位置,我们不去使用那些空位,只更新线段树用到的位置
if (pl == pr) {
tree[p] = a[pl]; return; //此时p=pl=pr,不明白的可以看看线段树的图解
}
int mid = (pl + pr) >> 2;
//搜索算法
build(ls(p), pl, mid);
build(rs(p), mid + 1, pr);
//直到叶子节点,递归回根节点的路上更新沿路区间和,即tree[p]的值
pushup(p);
}
//lazy_tag算法
void addtag(ll p,ll pl,ll pr,ll d) {
tag[p] += d;
tree[p] += (pl - pr + 1) * d;
}
//向下传递函数
void pushdown(ll p, ll pl, ll pr) {
if (tag[p]) {
//如果子节点有tag[p],则一直传递直到叶子节点
int mid = (pl + pr);
addtag(ls(p), pl, mid,tag[p]);
addtag(rs(p), mid + 1, pr,tag[p]);
tag[p] = 0;
}
}
//更新操作
void update(ll L, ll R, ll p, ll pl, ll pr, ll d) {
if (L <= pl && R >= pr) {
addtag(p, pl, pr, d);
return;
}
int mid = (pl + pr) >> 1; //这个是左中位数,所以下面的等号使用是有讲究的,原理类似于二分法,感兴趣的同学可自行查阅
if (L <= mid) update(L, R, ls(p), pl, mid, d);
if (R > mid) update(L, R, rs(p), mid + 1, pr, d);
//更新之后任然需要将更新信息传给与更新路径相关的节点
pushup(p);
}
//查询操作
ll query(ll L, ll R, ll p, ll pl, ll pr) {
if (L <= pl && R >= pr) {
return tree[p];
}
//将tag标记传递下去
pushdown(p, pl, pr);
ll res = 0;
int mid = (pl + pr) >> 1;
if (L <= mid) res += query(L, R, ls(p), pl, mid);
if (R > mid) res += query(L, R, rs(p), mid + 1, pr);
return res;
}
int main() {
ll n, m; cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
build(1, 1, n);
while (m--) {
ll q, l, r, d; cin >> q;
if (q == 1) {
cin >> l >> r >> d;
update(l, r, 1, 1, n, d);
}
if (q == 2) {
cin >> l >> r;
query(l, r, 1, 1, n);
}
}
return 0;
}
线段树 ----洛谷p3372的更多相关文章
- 线段树 洛谷P3932 浮游大陆的68号岛
P3932 浮游大陆的68号岛 题目描述 妖精仓库里生活着黄金妖精们,她们过着快乐,却随时准备着迎接死亡的生活. 换用更高尚的说法,是随时准备着为这个无药可救的世界献身. 然而孩子们的生活却总是无忧无 ...
- [线段树]洛谷P5278 算术天才⑨与等差数列
题目描述 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k ...
- 区间连续长度的线段树——洛谷P2894 [USACO08FEB]酒店Hotel
https://www.luogu.org/problem/P2894 #include<cstdio> #include<iostream> using namespace ...
- 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)
洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...
- 洛谷P3372 【模板】线段树 1
P3372 [模板]线段树 1 153通过 525提交 题目提供者HansBug 标签 难度普及+/提高 提交 讨论 题解 最新讨论 [模板]线段树1(AAAAAAAAA- [模板]线段树1 洛谷 ...
- 洛谷P3372线段树1
难以平复鸡冻的心情,虽然可能在大佬眼里这是水题,但对蒟蒻的我来说这是个巨大的突破(谢谢我最亲爱的lp陪我写完,给我力量).网上关于线段树的题解都很玄学,包括李煜东的<算法竞赛进阶指南>中的 ...
- 洛谷P3372线段树模板1——线段树
题目:https://www.luogu.org/problemnew/show/P3372 线段树模板. 代码如下: #include<iostream> #include<cst ...
- 洛谷 P3372 【模板】线段树 1
P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...
- 洛谷—— P3372 【模板】线段树 1
P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...
- 线段树入门详解,洛谷P3372 【模板】线段树 1
关于线段树: 本随笔参考例题 P3372 [模板]线段树 1 所谓线段树就是把一串数组拆分成一个一个线段形成的一棵树. 比如说像这样的一个数组1,2,3,4,5: 1 ~ 5 / ...
随机推荐
- 2024 暑假友谊赛-热身2 (7.12)zhaosang
E-E https://vjudge.net/problem/AtCoder-diverta2019_b 给你 a, b, c ,n就是问你有多少(ia+jb+k*c)等于n的答案i,j,k任意几个都 ...
- SUM-2024成信大天梯赛
查看代码中有仔细的批注 L1-5 yihan的新函数 题解:(字符串)需要用到一个知识,整数与字符串之间的变换"to_string()",字符串变成整数"stoll()& ...
- SpringBoot+ Sharding Sphere 轻松实现数据库字段加解密
一.介绍 在实际的软件系统开发过程中,由于业务的需求,在代码层面实现数据的脱敏还是远远不够的,往往还需要在数据库层面针对某些关键性的敏感信息,例如:身份证号.银行卡号.手机号.工资等信息进行加密存储, ...
- 【VMware VCF】VMware Cloud Foundation Part 04:准备 ESXi 主机。
VMware Cloud Foundation 管理域部署要求至少准备 4 台 ESXi 主机作为最小计算单元,如果采用整合部署(管理域和 VI 工作负载域合并),还需要根据实际情况适量增加 ESXi ...
- SpringBoot整合knife4j(swagger)
关于knife4j Knife4j是一个基于Swagger的Java接口文档生成工具,它提供了一套可视化的界面来展示和测试API接口.Knife4j通过解析接口代码中的Swagger注解,自动生成接口 ...
- 9、SpringMVC之处理静态资源
9.1.环境搭建 9.1.1.在project创建新module 9.1.2.选择maven 9.1.3.设置module名称和路径 9.1.4.module初始状态 9.1.5.配置打包方式和引入依 ...
- 【Vue2】金额范围查询项
Element 只提供了DatePicker,没有做金额的Picker 这个东西就只能自己做了,实现效果: 后台接口条件: 因为有可能只有起始值,只有结束值,或者起始值结束值都有三种情况 1.如果有起 ...
- 【Hearts Of Iron IV】钢铁雄心4 安装笔记
一.解决Steam购买游戏和下载问题 我可能是正版受害者 Steam平台这个游戏本体是购买锁国区的 然后在淘宝上面买激活码激活的 都激活过了的Key,所以放出来也无所谓了 钢铁雄心4学员版本体:7B0 ...
- 智慧城市(Smart City)—— 华为预测2025年的10大趋势( Huawei Predicts 10 Megatrends for 2025 )
原文: https://www.huawei.com/en/news/2019/8/huawei-predicts-10-megatrends-2025 相关: https://www.huawei. ...
- 《Python数据可视化之matplotlib实践》 源码 第三篇 演练 第八章
图 8.1 import matplotlib.pyplot as plt import numpy as np plt.axes([0.05, 0.7, 0.3, 0.3], frameon=Tr ...