poj 3648 线段树成段更新
线段树成段更新需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新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 线段树成段更新的更多相关文章
- POJ 3468 线段树 成段更新 懒惰标记
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072K Case Time Limit:2000MS Descr ...
- poj 3669 线段树成段更新+区间合并
添加 lsum[ ] , rsum[ ] , msum[ ] 来记录从左到右的区间,从右到左的区间和最大的区间: #include<stdio.h> #define lson l,m,rt ...
- poj 3468 线段树成段更新
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 54012 ...
- POJ 2777 Count Color (线段树成段更新+二进制思维)
题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...
- poj 3468 A Simple Problem with Integers 【线段树-成段更新】
题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...
- 线段树(成段更新) POJ 3468 A Simple Problem with Integers
题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ...
- ACM: Copying Data 线段树-成段更新-解题报告
Copying Data Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description W ...
- 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. 这题 ...
- hdu 4747【线段树-成段更新】.cpp
题意: 给出一个有n个数的数列,并定义mex(l, r)表示数列中第l个元素到第r个元素中第一个没有出现的最小非负整数. 求出这个数列中所有mex的值. 思路: 可以看出对于一个数列,mex(r, r ...
随机推荐
- 【Remove Duplicates from Sorted Array II】cpp
题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...
- [oldboy-django][1初识django]阻止默认事件发生 + ajax + 模态编辑对话框
阻止默认事件发生 a 阻止a标签默认事件发生方法 <a href="http://www.baidu.com" onclick="modalEdit();" ...
- File IO(NIO.2):路径类 和 路径操作
路径类 Java SE 7版本中引入的Path类是java.nio.file包的主要入口点之一.如果您的应用程序使用文件I / O,您将需要了解此类的强大功能. 版本注意:如果您有使用java.io. ...
- Log4j官方文档翻译(三、配置)
之前的章节介绍了log4j的核心组件,本章将会通过配置文件介绍一下核心组建的配置. 主要在配置文件中配置log4j的日志级别,定义appender.layout等. log4j.properties是 ...
- 12小时制时间&&24小时制时间
今天在获取时间的时候发现,插入到数据库中的时间,其中下午的时间直接显示01,02的样子...查了下资料发现了端倪, java.text.SimpleDateFormat f=new java.text ...
- Codeforces 954E Water Taps
题目大意 有 $n$($1\le n\le 200000$)个变量 $x_1, x_2, \dots, x_n$,满足 \begin{equation} 0\le x_i \le a_i \label ...
- ZOJ 2676 Network Wars(最优比例最小割)
Network Wars Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge Network of Bytelan ...
- linux系统——etc下的group 文件
etc/group 文件 用户组的所有信息都存放在/etc/group文件中 将用户分组是Linux系统中对用户进行管理及控制访问权限的一种手段.每个用户都属于某个用户组:一个组中可以有多个用户,一个 ...
- Apache+Openssl
Apache编译还需要一些依赖: #./configure --prefix……检查编辑环境时出现: checking for APR... no configure: error: APR not ...
- Databus架构分析与初步实践
简介 Databus是一个低延迟.可靠的.支持事务的.保持一致性的数据变更抓取系统.由LinkedIn于2013年开源.Databus通过挖掘数据库日志的方式,将数据库变更实时.可靠的从数据库拉取出来 ...