线段树 区间修改 单点查询

请先阅读上一篇Bolg

算法思想

由于是区间修改

那就把下放的每一个线段给套上一层标记

来表达增加的值

单点查询就把那些标记穿起来就行了

当然 还要加上那原来的值

来举个例子:

我想要更改绿色这段区间的值

那就在绿色这段上下推标记

然后我又想在蓝色这段上更改区间值

那就继续下推标记

如果我想要查询紫色的这个点的值

那就把一路上的标记(绿色和蓝色的)加起来

最后再把那个点原本的值加起来(黄色那一小段)

就是最终的值了

代码实现

变量含义详见上个Blog

有个新变量就是那个标记

就是 Node 结构体中的 k

Build函数和上个相同

添加标记

void add(int i,int l,int r,int k){
if(l <= tree[i].l && tree[i].r <= r){
tree[i].k += k;
return ;
}
if(tree[li].r >= l)
add(li,l,r,k);
if(tree[ri].l <= r)
add(ri,l,r,k);
}
  • \(l <= tree[i].l\) && \(tree[i].r <= r\)

这代表这个线段已经完全被包围了

那就把这个线段打上标记

并且要停止继续向下打标记

因为这段已经打上了

所以 \(return ;\)

  • \(tree[li].r >= l\)
  • \(tree[ri].l <= r\)

这里和上个相同

哪有搜哪里

单点查询

int search(int i,int dis,int ans){
if(tree[i].l == tree[i].r){
return val[dis] + tree[i].k;
}
if(dis <= tree[li].r)
return tree[i].k + search(li,dis,ans);
if(dis >= tree[ri].l)
return tree[i].k + search(ri,dis,ans);
}
  • \(tree[i].l == tree[i].r\)

已经查询到点了

那就返回点的值和这个线段上的标记

  • \(dis <= tree[li].r\)
  • \(dis >= tree[ri].l\)

如果没有到点

那就加上这个线段的标记

以及继续往下搜的结果

线段数 区间修改 区间查询

Code

#include<bits/stdc++.h>
#define maxn 1000010
#define mid ((l+r)>>1)
#define li i<<1
#define ri 1+(i<<1)
using namespace std; int n,val[maxn]; struct Node{
int l,r,sum,k;
}tree[maxn]; void Read(){
cin >> n;
for(int i = 1;i <= n;i++)cin >> val[i];
} void build(int i,int l,int r){
tree[i].l = l;
tree[i].r = r;
if(l == r){
tree[i].sum = val[l];
return ;
}
build(li,l,mid);
build(ri,mid+1,r);
tree[i].sum = tree[li].sum + tree[ri].sum;
return ;
} void add(int i,int l,int r,int k){
if(l <= tree[i].l && tree[i].r <= r){
tree[i].k += k;
return ;
}
if(tree[li].r >= l)
add(li,l,r,k);
if(tree[ri].l <= r)
add(ri,l,r,k);
} int search(int i,int dis,int ans){
if(tree[i].l == tree[i].r){
return val[dis] + tree[i].k;
}
if(dis <= tree[li].r)
return tree[i].k + search(li,dis,ans);
if(dis >= tree[ri].l)
return tree[i].k + search(ri,dis,ans);
} void interaction(){
while(1){
int tot;
cin >> tot;
if(tot == 1){
int dis;
cin >> dis;
cout << search(1,dis,0) << endl;
} else if(tot == 2){
int l,r,k;
cin >> l >> r >> k;
add(1,l,r,k);
} else if(tot == 3){
return ;
}
}
} int main(){
cout << "query point" << endl << "change section" << endl;
Read();
build(1,1,n);
cout << "query 1" << endl << "change 2" << endl << "break 3" << endl;
interaction();
return 0;
}

[C++]线段树 区间修改 单点查询的更多相关文章

  1. D - Mayor's posters POJ - 2528 离散化+线段树 区间修改单点查询

    题意 贴海报 最后可以看到多少海报 思路 :离散化大区间  其中[1,4] [5,6]不能离散化成[1,2] [2,3]因为这样破坏了他们的非相邻关系 每次离散化区间 [x,y]时  把y+1点也加入 ...

  2. HDU 5861 Road(线段树 区间修改 单点查询)

    Road Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  3. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  4. ZOJ 1610 Count the Colors【题意+线段树区间更新&&单点查询】

    任意门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610 Count the Colors Time Limit: 2 ...

  5. hdu 1166 敌兵布阵 线段树区间修改、查询、单点修改 板子题

    题目链接:敌兵布阵 题目: C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视 ...

  6. POJ 3468 A Simple Problem with Integers(线段树区间修改及查询)

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  7. HDU 5861 Road 线段树区间更新单点查询

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...

  8. ZOJ 1610 Count the Colors(线段树,区间覆盖,单点查询)

    Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting some colored segments on ...

  9. POJ 2528 Mayor's posters(线段树,区间覆盖,单点查询)

    Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45703   Accepted: 13239 ...

  10. Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)

    题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...

随机推荐

  1. 跟运维学 Linux - 01

    跟运维学 Linux - 01 运维的诞生 运维工程师有很多叫法:系统运维.Linux 工程师.系统管理员... 网管可以说是运维工程师最早的雏形.在个人电脑未普及时,大家去网吧玩游戏. 玩家:&qu ...

  2. ElementUi使用el-tooltip实现超出部分显示省略号

    效果前: 效果后: 创建myTooltio.vue组件 <template> <div class="tooltip-container"> <el- ...

  3. 2021-3-29 Enter按下事件

    先在构造器中添加keydown事件 tBoxPsw.KeyDown += TBoxPsw_KeyDown; 在事件中添加按下enter按钮所触发的方法 private void TBoxPsw_Key ...

  4. React:styled-components有趣的用法

    背景 用于记录一些styled-components的有趣的用法 绑定a标签的链接 编写伪类 在styleComponents中使用参数 传入参数

  5. 通过 tree shaking 移除无用代码

    tree shaking 依赖于ES Module 的静态语法分析,在项目编译时移除无用的代码以减少文件体积. usedExports 在文件中,我们可能定义了变量但是暂时又没有用到,这样会造成空间的 ...

  6. c++中unique_ptr 的使用和理解

    unique_ptr 的使用 std::unique_ptr是c++11起引入的智能指针,为什么必须要在c++11起才有该特性,主要还是c++11增加了move语义,否则无法对对象的所有权进行传递. ...

  7. 从0开始,Cloudreve开源云盘在centos7上部署,并可在外网访问(资料整合)

    全程我在网络上收集这些资料,太零碎了,每一个一看就会,一动手就废,而且很多都不能实现我白嫖的梦想 我一个人折腾了快一周,现在可以正常访问手机电脑多端访问 给个赞再走吧 此处为没有公网IP(回去折腾你家 ...

  8. SpringBoot如何整合spring-retry来实现接口请求重试

    一.重试机制 由于网络不稳定或网络抖动经常会造成接口请求失败的情况,当我们再去尝试就成功了,这就是重试机制. 其主要目的就是要尽可能地提高请求成功的概率,但一般情况下,我们请求第一次失败,代码运行就抛 ...

  9. 历时数月钻研推流/对比各种流媒体服务程序/PK总结

    1 前言 大量测试下来,网页显示视频流实时性从高到低依次是 webrtc > ws-flv > flv > hls.播放器打开rtsp/rtmp视频流实时性由具体的播放器控制,比如缓 ...

  10. Programming abstractions in C阅读笔记:p127-p129

    <Programming Abstractions In C>学习第51天,p127-p129,总结如下: 一.技术总结 1. string library 掌握常用函数如strlen,s ...