线段树成段更新需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新or询问到的时候。延迟标记的意思是:这个区间的左右儿子都需要被更新,但是当前区间已经更新了。其主要使用了Lazy思想。

Lazy思想:lazy-tag思想,记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。
在此通俗的解释Lazy(t偷懒)的意思,比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,它的节点标记为rt,这时tree[rt].l == a && tree[rt].r == b 这时我们可以一步更新此时rt节点的sum[rt]的值,sum[rt] += c * (tree[rt].r - tree[rt].l + 1),注意关键的时刻来了,如果此时按照常规的线段树的update操作,这时候还应该更新rt子节点的sum[]值,而Lazy思想恰恰是暂时不更新rt子节点的sum[]值,到此就return,直到下次需要用到rt子节点的值的时候才去更新,这样避免许多可能无用的操作,从而节省时间 。

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
const int MAXN = +;
typedef long long LL;
using namespace std;
struct Tnode{
int b, e;
LL sum; //当前区间和
LL mark; //延迟标记
};
Tnode tree[*MAXN];
int n;
void Build(int v, int b, int e){
tree[v].b = b, tree[v].e = e;
tree[v].sum=tree[v].mark = ;
if (b < e){
int mid = (b + e) >> ;
Build( * v + , b, mid);
Build( * v + , mid + , e);
}
}
void update(int v, int l, int r, LL value){
if (l == tree[v].b&&r == tree[v].e){
tree[v].mark += value; //该区间每个数都要增加value,它的子区间可以先不更新(Lazy)
return; //直接返回了
}
tree[v].sum += value*(r - l + ); //将增加的值更新进去
int mid = (tree[v].b + tree[v].e) >> ;
if (r <= mid)
update( * v + , l, r, value);
else if (l > mid)
update( * v + , l, r, value);
else{
update( * v + , l, mid, value);
update( * v + , mid + , r, value);
}
}
LL Qurrey(int v, int l, int r){
if (tree[v].b==l&&tree[v].e==r)
return tree[v].sum+(r-l+)*tree[v].mark;
if (tree[v].mark != ){ //之前欠的债现在要还了
//如果当前区间mark不为0,则将它传递给子区间
tree[ * v + ].mark += tree[v].mark;
tree[ * v + ].mark += tree[v].mark;
tree[v].sum += tree[v].mark*(tree[v].e-tree[v].b+);
tree[v].mark = ;
}
int mid = (tree[v].b + tree[v].e) >> ;
if (r <= mid)
return Qurrey( * v + , l, r);
else if (l > mid)
return Qurrey( * v + , l, r);
else
return Qurrey( * v + , l, mid) + Qurrey( * v + , mid + , r); }
int main(){
long long x;
int a, b,i,q;
char ch;
scanf("%d%d", &n, &q);
Build(, , n);
for (i = ; i <= n; i++){
scanf("%lld", &x);
update(, i, i, x);
}
while (q--){
cin >> ch;
scanf("%d%d", &a, &b);
if (ch == 'Q')
printf("%lld\n", Qurrey(, a, b));
else{
scanf("%lld", &x);
update(, a, b, x);
}
}
return ;
}

poj 3648 线段树成段更新的更多相关文章

  1. POJ 3468 线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  2. poj 3669 线段树成段更新+区间合并

    添加 lsum[ ] , rsum[ ] , msum[ ] 来记录从左到右的区间,从右到左的区间和最大的区间: #include<stdio.h> #define lson l,m,rt ...

  3. poj 3468 线段树成段更新

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 54012   ...

  4. POJ 2777 Count Color (线段树成段更新+二进制思维)

    题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...

  5. poj 3468 A Simple Problem with Integers 【线段树-成段更新】

    题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...

  6. 线段树(成段更新) POJ 3468 A Simple Problem with Integers

    题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ...

  7. ACM: Copying Data 线段树-成段更新-解题报告

    Copying Data Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description W ...

  8. Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

    题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...

  9. hdu 4747【线段树-成段更新】.cpp

    题意: 给出一个有n个数的数列,并定义mex(l, r)表示数列中第l个元素到第r个元素中第一个没有出现的最小非负整数. 求出这个数列中所有mex的值. 思路: 可以看出对于一个数列,mex(r, r ...

随机推荐

  1. @SpringBootApplication的扫描范围

    在公共类自定义一个全局异常类,实现全局捕获异常,在另一个服务中调用的时候,发现没有生效 因此我添加了一个@ComponentScan("com.wuhen.jwt.common") ...

  2. Leetcode 647.回文子串

    回文子串 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串. 示例 1: 输入: "abc&qu ...

  3. [python][django学习篇][9]设计正在博客视图(3)

    需求: 真正的首页视图函数,当用户访问我们的博客首页时,他将看到我们发表的博客文章列表,就像 演示项目 里展示的这样.t https://docs.djangoproject.com/en/1.10/ ...

  4. 什么是虚假唤醒 spurious wakeup

    解释一下什么是虚假唤醒? 说具体的例子,比较容易说通. pthread_mutex_t lock; pthread_cond_t notempty; pthread_cond_t notfull; v ...

  5. MFC录制音频和播放音频

    一.录制音频 在windows中提供了相应的API函数(waveIn这个族的函数)实现录音功能:在使用这些函数时,一定要引入相应的头文件 #include <windows.h> #inc ...

  6. 四则运算UI组结对作业报告

    Github提交地址: 小组成员:陈兆庭,陈昶金: 一.编程阶段 清明节开始接触和调研关于UI设计的方法.由于两人的各方面知识储备均不足,在各种东西C#.MFC.Qt中进行调查和讨论,最终因为网上说Q ...

  7. win 8系统下如何安装搭建python

    python的环境搭建除了python本身,还有Aptana和pip的安装.Aptana提供了更好的集成开发环境,pip主要用于安装第三方的包. 具体安装流程可参考以下两篇文章: InSky关于安装p ...

  8. Vagrant Tip: Virtualbox Guest Additions

    Vagrant Tip: Virtualbox Guest Additions 12 February 2016 Tired of seeing this message when you run v ...

  9. Struts2 改变语言状态

    只要在请求中增加 request_locale=en_US 参数,就可以实现语言的切换,内部由拦截器实现

  10. windows通过NSF挂载centos目录

    windows通过NSF挂载centos目录 来源: http://blog.csdn.net/u012955038/article/details/77151346 CentOS 配置 1.安装NF ...