POJ - 3468 线段树区间修改,区间求和
由于是区间求和,因此我们在更新某个节点的时候,需要往上更新节点信息,也就有了tree[root].val=tree[L(root)].val+tree[R(root)].val;
但是我们为了把懒标记打上,当节点表示的区间是完全被询问区间包含,那么这个区间的信息都是有用的,因此我们其实只需要把这个节点更新,并打上懒标记即可。如果以后update 或者 query 需要跑到下面,直接往下pushdown即可。
pushdown的时候,由于当前层的信息已经更新,我们需要把信息往下推,并把子节点的信息维护,因此需要把laze标记往下打,并且往下更新修改即可
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = ;
long long sum;
inline int L(int r)
{
return r<<;
}
inline int R(int r)
{
return r<<|;
}
inline int MID(int l,int r)
{
return (l+r)>>;
}
struct node
{
int left,right;
long long val,add;
} tree[maxn<<];
long long b[maxn];
void pushdown(int root)
{
if (tree[root].add) //这个节点内部需要往下更新
{
tree[L(root)].add+=tree[root].add;//把laze标记往下传递 以后再进行更深的节点
tree[R(root)].add+=tree[root].add;
tree[L(root)].val+=(tree[L(root)].right-tree[L(root)].left+)*tree[root].add;//laze标记应该标记在自己的本身的位置 去改变下一个位置
tree[R(root)].val+=(tree[R(root)].right-tree[R(root)].left+)*tree[root].add;
tree[root].add=;//消除标记
}
}
void buildtree(int root,int l,int r)
{
tree[root].left=l;
tree[root].right=r;
tree[root].add=;
if(l==r)
{
tree[root].val=b[l];
return;
}
int mid=MID(l,r);
buildtree(L(root),l,mid);
buildtree(R(root),mid+,r);
tree[root].val=tree[L(root)].val+tree[R(root)].val;
}
void update(int root,int l,int r,long long v)
{
if(l<=tree[root].left && tree[root].right<=r)//包含在询问的区间内部
{
tree[root].add+=v;//打上标记
tree[root].val+=v*(tree[root].right-tree[root].left+);//修改
return;
}
pushdown(root);
if(tree[root].left==tree[root].right)
{
return;
}
int mid=MID(tree[root].left,tree[root].right);
if(l>mid)
update(R(root),l,r,v);//左区区间仅仅在右儿子节点中
else if (r<=mid)update(L(root),l,r,v);//仅仅在左儿子节点中
else
{
update(L(root),l,mid,v);//继续向下询问
update(R(root),mid+,r,v);//继续向下询问
}
tree[root].val=tree[L(root)].val+tree[R(root)].val;//把更新往上修改
}
void query(int root,int l,int r)
{
if (l<=tree[root].left && tree[root].right<=r)
{
sum+=tree[root].val;
return;
}
pushdown(root);
if(tree[root].left==tree[root].right)return;
int mid=MID(tree[root].left,tree[root].right);
if (l>mid)query(R(root),l,r);
else if (r<=mid)query(L(root),l,r);
else
{
query(L(root),l,mid);
query(R(root),mid+,r);
}
}
int main()
{
int n,m;
char op;
int tmp1,tmp2;
long long tmp3;
while(~scanf("%d%d",&n,&m))
{
for (int i=; i<=n; i++)
{
scanf("%lld",&b[i]);
}
buildtree(,,n);
while(m--)
{
scanf(" %c",&op);
if (op=='Q')
{
scanf("%d%d",&tmp1,&tmp2);
sum=;
query(,tmp1,tmp2);
printf("%lld\n",sum);
}
else
{
scanf("%d%d%lld",&tmp1,&tmp2,&tmp3);
update(,tmp1,tmp2,tmp3);
}
}
}
return ;
}
POJ - 3468 线段树区间修改,区间求和的更多相关文章
- poj 3468(线段树)
http://poj.org/problem?id=3468 题意:给n个数字,从A1 …………An m次命令,Q是查询,查询a到b的区间和,c是更新,从a到b每个值都增加x.思路:这是一个很明显的线 ...
- POJ - 3468 线段树单点查询,单点修改区间查询,区间修改模板(求和)
题意: 给定一个数字n,表示这段区间的总长度.然后输入n个数,然后输入q,然后输入a,b,表示查询a,b,区间和,或者输入c 再输入三个数字a,b,c,更改a,b区间为c 思路: 线段树首先就是递归建 ...
- C - A Simple Problem with Integers POJ - 3468 线段树模版(区间查询区间修改)
参考qsc大佬的视频 太强惹 先膜一下 视频在b站 直接搜线段树即可 #include<cstdio> using namespace std; ; int n,a[maxn]; stru ...
- poj 3468 线段树 成段增减 区间求和
题意:Q是询问区间和,C是在区间内每个节点加上一个值 Sample Input 10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4Sample O ...
- POJ 3468 线段树区间修改查询(Java,c++实现)
POJ 3468 (Java,c++实现) Java import java.io.*; import java.util.*; public class Main { static int n, m ...
- hdu 1698+poj 3468 (线段树 区间更新)
http://acm.hdu.edu.cn/showproblem.php?pid=1698 这个题意翻译起来有点猥琐啊,还是和谐一点吧 和涂颜色差不多,区间初始都为1,然后操作都是将x到y改为z,注 ...
- HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- poj 3468 线段树区间更新/查询
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- POJ 3468 (线段树 区间增减) A Simple Problem with Integers
这题WA了好久,一直以为是lld和I64d的问题,后来发现是自己的pushdown函数写错了,说到底还是因为自己对线段树理解得不好. 因为是懒惰标记,所以只有在区间分开的时候才会将标记往下传递.更新和 ...
- POJ 3468<线段树,区间add>
题目连接 //位运算 k<<1 相当于 k*2 k<<1|1 相当于 k*2+1 /* 修改区间内的值,并且维护区间和. 详见代码 */ #include<cstdio& ...
随机推荐
- 使用GDB调试gp(转载)
使用 gdb 调试 postgres greenplum zalax3030人评论715人阅读2012-07-11 10:07:15 错误信息的获取途径有几种 : 1. 最简单的就是看Postg ...
- python第一百六十九天,第十九周作业
FIRSTCRM 学员管理开发需求: 1.分讲师\学员\课程顾问角色, 2.学员可以属于多个班级,学员成绩按课程分别统计 3.每个班级至少包含一个或多个讲师 4.一个学员要有状态转化的过程 ,比如未报 ...
- mysql统计一年12月的数据
效果图: select end) as 一月份, end) as 二月份, end) as 三月份, end) as 四月份, end) as 五月份, end) as 六月份, end) as 七月 ...
- node基础—模块系统
模块的概念 为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块加载系统. 在 Node.js 中,文件和模块是一一对应的(每个文件被视为一个独立的模块),换言之,一个 Node ...
- MySQL高级知识(九)——慢查询日志
前言:慢查询日志是MySQL提供的一种日志记录,它记录MySQL中响应时间超过阈值的语句,具体指运行时间超过long_query_time值的sql语句,该sql语句会被记录到慢查询日志中.慢查询日志 ...
- Zend:PHP框架结束的开始?
Zend:PHP框架结束的开始? 随着Zeev Suraski, Matthew Weier O'Phinney, Enrico Zimuel and Dmitry Stogov 这些PHP核心小组的 ...
- Linux之权限详解
如何知道你有什么权限 我能干什么?这是我最关心的问题! 切换到普通用户 [root@luffy-01 ~]# su - pizza [pizza@luffy-01 ~]$ ls /root ls: c ...
- 如何在excel单元格中插入图片批注
在excel单元格中插入图片批注的方法: 1.选定要插入图片的单元格,然后右键选择插入批注. 2.然后会插入一个批注框,为了不影响图片效果,可以将批注文字都删除.然后鼠标移动到批注框边角再右键. 3. ...
- C#定时备份正在播放的幻灯片、word文档、excel电子表格,mht格式文档
控制台应用, 代码如下: using System; using System.Collections.Generic; using System.IO; using System.Linq; usi ...
- 洛谷P1274-魔术数字游戏
Problem 洛谷P1274-魔术数字游戏 Accept: 118 Submit: 243Time Limit: 1000 mSec Memory Limit : 128MB Probl ...