对于朴素线段树,要进行区间更新,如果按照单点更新的方法更新,他的复杂度很高,比数组暴力更新还要慢。
所以我们使用懒惰标记,他走到包含区间就不往下走了,然后就更新区间值,并打上懒惰标记。那走到这不走了,他下面的没更新怎么办,这时候就是懒惰标记的用处了,我打上懒惰标记,那我下次往下走的时候我把这个值加上不就行了(也就是懒惰标记的值)

如更新2到10区间的值,那么我走到绿色勾处就不往下走了,打上懒惰标记。

void pushdown(int now,int l,int r){//下推懒惰标记tree[now*2].lazymark+=tree[now].lazymark;tree[now*2+1].lazymark+=tree[now].lazymark;//更新儿子值int mid=(l+r)/2;tree[now*2].sum+=tree[now].lazymark*(mid-l+1);tree[now*2+1].sum+=tree[now].lazymark*(r-mid);//下推后当前懒惰标记置零tree[now].lazymark=0;
}


更新

void update(int now,int x,int y,int add){if(x<=tree[now].l&&tree[now].r<=y){tree[now].lazymark+=add;tree[now].sum+=(tree[now].r-tree[now].l+1)*add;return ;}if(tree[now].lazymark)pushdown(now,tree[now].l,tree[now].r);int mid=(tree[now].l+tree[now].r)/2;if(y<=mid)update(now*2,x,y,add);else if(x>mid)update(now*2+1,x,y,add);else{update(now*2,x,y,add);update(now*2+1,x,y,add);}pushup(now);  //更新到最下面,也要向上更新 和朴素线段树一样
}

查询

int search(int now,int x,int y){if(x<=tree[now].l&&tree[now].r<=y){return tree[now].sum;}if(tree[now].lazymark)pushdown(now,tree[now].l,tree[now].r);int mid=(tree[now].l+tree[now].r)/2;if(y<=mid)return search(now*2,x,y);else if(x>mid)return search(now*2+1,x,y);else{return search(now*2,x,y)+search(now*2+1,x,y);}
}

问题 A: 敌兵布阵

题目描述
C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手但这些都逃不过C国的监视。
中央情报局要研究敌人究竟演习什么战术所以Tidy要随时向Derek汇报某一段连续的工兵营地一共有多少人例如Derek问:“Tidy马上汇报第3个营地到第10个营地共有多少人!”Tidy就要马上开始计算这一段的总人数并汇报。但敌兵营地的人数经常变动,而Derek每次询问的段都不一样,所以Tidy不得不每次都一个一个营地的去数,很快就精疲力尽了,Derek对Tidy的计算速度越来越不满:"你个死肥仔,算得这么慢,我炒你鱿鱼!”Tidy想:“你自己来算算看,这可真是一项累人的工作!我恨不得你炒我鱿鱼呢!”无奈之下,Tidy只好打电话向计算机专家Windbreaker求救Windbreaker说:“死肥仔,叫你平时做多点acm题和看多点算法书,现在尝到苦果了吧!”Tidy说:"我知错了。。。"但Windbreaker已经挂掉电话了。Tidy很苦恼,这么算他真的会崩溃的,聪明的读者,你能写个程序帮他完成这项工作吗?不过如果你的程序效率不够高的话,Tidy还是会受到Derek的责骂的.
输入
第一行一个整数T,表示有T组数据。
每组数据第一行一个正整数N(N<=50000)表示敌人有N个工兵营地,接下来有N个正整数第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=109)。
接下来每行有一条命令,命令有4种形式:
(1) Add i ji和j为正整数表示第i个营地增加j个人(j不超过30)
(2)Sub i j i和j为正整数表示第i个营地减少j个人(j不超过30);
(3)Query i j i和j为正整数i<=j,表示询问第i到第j个营地的总人数;
(4)End 表示结束,这条命令在每组数据最后出现;
每组数据最多有40000条命令
输出
对第i组数据首先输出“Case i:”和回车
对于每个Query询问,输出一个整数并回车表示询问的段中的总人数这个数保持在int以内。
样例输入
1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End
样例输出
Case 1:
6
33
59

#include<bits/stdc++.h>
using namespace std;const int maxn=500000+5;
struct node{int sum;int l;int r;int lazymark;
}tree[maxn];
int num[maxn];void pushup(int k){tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
}void pushdown(int now,int l,int r){tree[now*2].lazymark+=tree[now].lazymark;tree[now*2+1].lazymark+=tree[now].lazymark;int mid=(l+r)/2;tree[now*2].sum+=tree[now].lazymark*(mid-l+1);tree[now*2+1].sum+=tree[now].lazymark*(r-mid);tree[now].lazymark=0;
}void build(int now,int l,int r){tree[now].l=l;tree[now].r=r;if(l==r){tree[now].sum=num[l];return ;}int mid=(l+r)/2;build(now*2,l,mid);build(now*2+1,mid+1,r);pushup(now);
}void update(int now,int x,int y,int add){if(x<=tree[now].l&&tree[now].r<=y){tree[now].lazymark+=add;tree[now].sum+=(tree[now].r-tree[now].l+1)*add;return ;}if(tree[now].lazymark)pushdown(now,tree[now].l,tree[now].r);int mid=(tree[now].l+tree[now].r)/2;if(y<=mid)update(now*2,x,y,add);else if(x>mid)update(now*2+1,x,y,add);else{update(now*2,x,y,add);update(now*2+1,x,y,add);}pushup(now);
}int search(int now,int x,int y){if(x<=tree[now].l&&tree[now].r<=y){return tree[now].sum;}if(tree[now].lazymark)pushdown(now,tree[now].l,tree[now].r);int mid=(tree[now].l+tree[now].r)/2;if(y<=mid)return search(now*2,x,y);else if(x>mid)return search(now*2+1,x,y);else{return search(now*2,x,y)+search(now*2+1,x,y);}
}int main(){int t,x,y,n;string czzl;cin>>t;for(int l=1;l<=t;l++){cin>>n;printf("Case %d:\n",l);memset(tree, 0, sizeof(tree));memset(num,0,sizeof(num));for(int i=1;i<=n;i++){cin>>num[i];}build(1,1,n);while(cin>>czzl){if(czzl=="Add"){cin>>x>>y;update(1,x,x,y);}else if(czzl=="Sub"){cin>>x>>y;update(1,x,x,-y);}else if(czzl=="Query"){cin>>x>>y;cout<<search(1,x,y)<<endl;}else break;}}return 0;
}

线段树进阶(懒惰标记)相关推荐

  1. HDU 3397 线段树 双懒惰标记

    这个是去年遗留历史问题,之前思路混乱,搞了好多发都是WA,就没做了 自从上次做了大白书上那个双重懒惰标记的题目,做这个就思路很清晰了 跟上次大白上那个差不多,这个也是有一个sets标记,代表这个区间全 ...

  2. 【总结】线段树 进阶

    我竟然开了这么多坑...ε=(´ο`*)))唉,慢慢填吧... 线段树 进阶 前置芝士 然后我们来讲一个好玩的东西,叫权值线段树. 权值线段树&动态开点 有一个数列,数列里的每个不同的 aia ...

  3. 51nod3077 线段树进阶1

    3077 线段树进阶1 给出一个长度为n的整数序列a1,a2,-,an,进行m次操作,操作分为两类. 操作1 ​:给出l,r,v,将al,al+1,-,ar分别加上v. 操作2 ​:给出l,r,询问 ...

  4. 数据结构之线段树进阶(区间更新lazy标记)

    之前说了线段树的点更新和区间求和.其实点更新是区间更新的一种最基础的做法.我们把一个点想像成一个区间的话,不就是最简单的区间更新了嘛. 为什么要把区间更新和点更新分开来看呢?假如我们对区间[l,r]进 ...

  5. FZU 2171(线段树的延迟标记)

    题意:容易理解. 分析:时隔很久,再一次写了一道线段树的代码,之前线段树的题也做了不少,包括各种延迟标记,但是在组队分任务之后,我们队的线段树就交给了另外一个队友在搞, 然后我就一直没去碰线段树的题了 ...

  6. 线段树之延时标记(区间修改)及lazy思想

    暴力求解 1.最简单的方法是:在主函数中添加一个循环  进行 r-l+1次单点修改实现区间修改,对于单个元素修改时间复杂度为 O(log2(n)) 所以对于单个区间修改的时间复杂度为 O(n*log( ...

  7. 【BZOJ-28921171】强袭作战大sz的游戏 权值线段树+单调队列+标记永久化+DP...

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MB Submit: 45  Solved: 30 [Submit][Status][Discuss] ...

  8. POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)

    题目链接:http://poj.org/problem?id=3237 一棵有边权的树,有3种操作. 树链剖分+线段树lazy标记.lazy为0表示没更新区间或者区间更新了2的倍数次,1表示为更新,每 ...

  9. 线段树进阶之模板观见

    ----------------------已识乾坤大,犹怜草木青. 先介绍一篇优秀的洛谷博文:https://www.luogu.org/problemnew/solution/P3372 ---- ...

最新文章

  1. 3.15好水指数N1能否让饮水健康不失控?
  2. OSChina 周日乱弹 —— 冬季忧郁症五大特征
  3. 爱情,没有对不起;只有不珍惜……[
  4. intel 965集成显卡开启ubuntu9.10的3d效果
  5. JVM内存占用情况深入分析,分分钟解开你的疑惑
  6. 5 Jedis 操作
  7. kafka架构:分区机制详解
  8. 转载——逻辑回归的袅娜曲线,你是否会过目难忘?
  9. ACM MM2018 Best Paper 被华人包揽
  10. python万年历源代码_python万年历实现代码 含运行结果
  11. 12.二叉树的序遍历
  12. Spring Boot 2 尝鲜-动态 Banner
  13. 更改电脑外部串口端口COM号
  14. Android ListView常用用法(结合长按、数据库等)
  15. 恶意混时间你不敢管,却要吓唬全体员工?
  16. 谷歌浏览器怎么登录及开启同步功能
  17. 用PS给证件照换底色
  18. Unity3D接入移动MM支付SDK(强联网)的问题
  19. 济南推动大数据产业发展 居民生活将有新变化
  20. 俄罗斯计划推出数字卢布 逐年解锁推进?国际货币金融体系迈入数字化变革

热门文章

  1. ICP算法进行点云匹配
  2. AndroidStudio的Gradle完全教程
  3. java窗体中添加图片_在java窗体程序中添加图片的方法
  4. Eclipse IDE的使用
  5. 一个嵌入式牛人学习经历
  6. ## 嵌入式软件编程
  7. Request header field x-xsrf-token is not allowed by Access-Control-Allow-Headers in preflight respon
  8. Carson带你学Android:这是一份全面详细的属性动画学习攻略!
  9. LOG的含义 : Mysql 之 binlog介绍
  10. 从零构建知识图谱-第二章知识图谱技术体系