问题描述:

已知一个数列,对数列进行两种操作: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的更多相关文章

  1. 线段树 洛谷P3932 浮游大陆的68号岛

    P3932 浮游大陆的68号岛 题目描述 妖精仓库里生活着黄金妖精们,她们过着快乐,却随时准备着迎接死亡的生活. 换用更高尚的说法,是随时准备着为这个无药可救的世界献身. 然而孩子们的生活却总是无忧无 ...

  2. [线段树]洛谷P5278 算术天才⑨与等差数列

    题目描述 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k ...

  3. 区间连续长度的线段树——洛谷P2894 [USACO08FEB]酒店Hotel

    https://www.luogu.org/problem/P2894 #include<cstdio> #include<iostream> using namespace ...

  4. 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)

    洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...

  5. 洛谷P3372 【模板】线段树 1

    P3372 [模板]线段树 1 153通过 525提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 [模板]线段树1(AAAAAAAAA- [模板]线段树1 洛谷 ...

  6. 洛谷P3372线段树1

    难以平复鸡冻的心情,虽然可能在大佬眼里这是水题,但对蒟蒻的我来说这是个巨大的突破(谢谢我最亲爱的lp陪我写完,给我力量).网上关于线段树的题解都很玄学,包括李煜东的<算法竞赛进阶指南>中的 ...

  7. 洛谷P3372线段树模板1——线段树

    题目:https://www.luogu.org/problemnew/show/P3372 线段树模板. 代码如下: #include<iostream> #include<cst ...

  8. 洛谷 P3372 【模板】线段树 1

    P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...

  9. 洛谷—— P3372 【模板】线段树 1

    P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...

  10. 线段树入门详解,洛谷P3372 【模板】线段树 1

    关于线段树: 本随笔参考例题      P3372 [模板]线段树 1 所谓线段树就是把一串数组拆分成一个一个线段形成的一棵树. 比如说像这样的一个数组1,2,3,4,5: 1 ~ 5 /       ...

随机推荐

  1. JuiceFS 直连 NFS 新功能介绍,赋能 NAS 进行 AI 训练

    NAS 通过提供多用户网络数据存取服务,极大地简化了数据共享和管理.而 NFS 作为实现这种共享的一种主流协议,尽管广泛应用,但在处理复杂的 AI 训练场景时常常受限于其性能和一致性问题. Juice ...

  2. 辅助分类器生成对抗网络( Auxiliary Classifier Generative Adversarial Network,ACGAN)(附带pytorch代码)

    1 ACGAN基本原理 1.2 ACGAN模型解释 ACGAN相对于CGAN使的判别器不仅可以判别真假,也可以判别类别 .通过对生成数据类别的判断,判别器可以更好地传递loss函数使得生成器能够更加准 ...

  3. Linux 破解mysql密码

    mysql忘记密码怎么办 [root@master ~]# mysql -uroot -pHuawei123123$ mysql: [Warning] Using a password on the ...

  4. adb shell 批处理文件

    adb shell 批处理文件 手机截屏,并把图片传到电脑

  5. sql语句排序无效的问题

    数据可视化时因为数据类型排序无效的问题:这是由于你要排序的类型是String类型的而ORDER BY 方法排序要求整数型. 这就需要在ORDER BY 后加 CAST(需要排序的字段 AS UNSIG ...

  6. Jmeter函数助手32-UUID

    UUID函数用于返回一个伪随机类型4通用唯一标识符(UUID).该函数没有参数,直接引用即可

  7. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-60 - 判断元素是否显示 - 下篇

    1.简介 有些页面元素的生命周期如同流星一闪,昙花一现.我们也不知道这个元素在没在页面中出现过,为了捕获这一美好瞬间,让其成为永恒.我们就来判断元素是否显示出现过. 在操作元素之前,可以先判断元素的状 ...

  8. Linux下查看压缩文件内容的 10 种方法【转】

    转载地址:https://zhuanlan.zhihu.com/p/91593509 1.使用 Vim 编辑器 Vim 不仅仅是编辑器,它还包含其他许多强大的功能.下面的命令将直接显示压缩归档文件的内 ...

  9. 【JDBC】Extra03 PostgreSQL-JDBC

    PostgreSQL的JDBC实现: <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --> <d ...

  10. Google搜索居然也搞言论封锁

    昨天的一个blog: https://www.cnblogs.com/devilmaycry812839668/p/18334275 居然被Google搜索封禁了: 老美,你的言论自由呢???怎么到了 ...