线段树 区间修改 单点查询

请先阅读上一篇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. python添加水印

    # coding:utf-8 from PIL import Image, ImageDraw, ImageFont def add_text_to_image(image, text): font ...

  2. javascript高级程序设计第三版FileApi 学习与实践1

    文件操纵 File API File API 在表单中的文件输入字段的基础上,又添加了一些直接访问文件信息的接口. H5 在 DOM 元素中为文件输入元素添加了一个 files 集合. 在通过文件输入 ...

  3. 策略模式+Spring配置类优化多if..else思路

    图示 1. 现状 场景: 假设设备上报不同类型的消息,我们要对不同类型的消息做不同的处理.如果我们通过if..else的方式处理的话会显得比较冗余. 例如: if("alarmEvent&q ...

  4. Django错误:ERRORS: ?: (staticfiles.E001) The STATICFILES_DIRS setting is not a tuple or list. HINT: Perhaps you forgot a trailing comma?

    报错的原因是因为我们的STATICFILES_DIRS赋值时,形式不对,其应该赋数组对象,具体如下: 找到settings.py文件, 把 STATICFILES_DIRS=(os.path.join ...

  5. 微服务项目使用RabbitMQ

    微服务项目使用RabbitMQ 很久未用RabbitMQ了,根据网上的Demo,大多数是一个服务包含所有的生产者和消费者和配置,当自己去搭建服务的时候,还需要一些思考各种包的划分.无法无脑CV大法,所 ...

  6. 定义一个函数,传入一个字典和一个元组,将字典的值(key不变)和元组的值交换,返回交换后的字典和元组

    知识点:zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表. li=[3,4,5] t=(7,8,9) print(list(zip(li,t ...

  7. 如何利用AI智能聊天机器人10秒钟做出一个故事绘本的神奇插件

    原文链接:如何利用AI智能聊天机器人10秒钟做出一个故事绘本的神奇插件 ChatGPT以下称为AI智能聊天机器人 一.AI智能聊天机器人4中集成"Stories"插件 对于已经熟悉 ...

  8. Pytorch语法——torch.autograd.grad

    The torch.autograd.grad function is a part of PyTorch's automatic differentiation package and is use ...

  9. ArcMap中矢量数据修改标注Label的方法

      本文介绍在ArcMap软件中,修改图层标签(Label)所显示字段与具体显示内容的方法.   在之前的文章中,我们看到了ArcMap中修改图层标签的重要性:可是,如何自定义图层的标签内容呢?    ...

  10. 解决SVN死锁问题

    svn执行clean up后出现提示:svn cleanup failed–previous operation has not finished; run cleanup if it was int ...