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& ...
随机推荐
- js获取地址栏中的数据
window.location.href:设置或获取整个 URL 为字符串window.location.pathname:设置或获取对象指定的文件名或路径window.location.search ...
- 数据库之mysql篇(3)—— mysql创建/修改数据表/操作表数据
创建数据表:create table 数据表名 1.创建表规范 create table 表名( 列名 数据类型 是否为空 自动排序/默认值 主键/外键/唯一键, 列名 数据类型 ...
- iOS 让视图UIView 单独显示某一侧的边框线
有时候需要让view显示某一侧的边框线,这时设置layer的border是达不到效果的.在网上查阅资料发现有一个投机取巧的办法,原理是给view的layer再添加一个layer,让这个layer充当边 ...
- irc 关键操作
IRC 客户端: Textual 5 HexChat IRC 用户密码常用命令: 用户密码: 忘记密码 如果太长时间没登录IRC,难免会忘记密码,那IRC有重置密码的功能吗?当然有,不过也是通过命令 ...
- PHP匿名函数
PHP匿名函数 匿名函数(Anonymous functions),也叫闭包函数(closures),允许临时创建一个没有指定名称的函数.最经常用作回调函数(callback)参数的值. 举例: &l ...
- react 之 reflux 填坑
注意:老铁些,在看这篇文章的之前,最好了解一下react 的全局状态管理库哦,不然可能会坐飞机. ^_^ React 之reflux (它是一个功能模块,需要安装引入): import Reflux ...
- February 26th, 2018 Week 9th Monday
A good beginning is half done. 良好的开端是成功的一半. We can't finish anything if we don't start, sometimes ge ...
- ELK+Kafka 企业日志收集平台(一)
背景: 最近线上上了ELK,但是只用了一台Redis在中间作为消息队列,以减轻前端es集群的压力,Redis的集群解决方案暂时没有接触过,并且Redis作为消息队列并不是它的强项:所以最近将Redis ...
- 创建 tomcat 服务的镜像
如何设计 Tomcat 的 Dockerfile $ sudo docker search tomcat |wc -l 285 在 dockerhub 上搜索与 tomcat 相关的镜像,有如此之多的 ...
- ES5-ES6-ES7_函数的扩展
call()/apply()/bind()的用法 Function.prototype.bind(obj) :将函数内的this绑定为obj, 并将函数返回 function foo() { cons ...