POJ 3468 A Simple Problem with Integers(线段树区间修改及查询)
Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval.
The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15 线段树区间查询的核心思想是Lazy原则,顾名思义,懒!!
就是当修改某区间的值是,现将修改的值记录下来,暂不修改。
此时如果查询区间与上一个修改区间没有交集,那么对结果也没有影响。我等用到这个修改过的区间的值时,再将它的值向下更新。
而且只用向下更新一层,因为递归时我们是根据区间的位置情况连续向下找左右子节点的,所以只更新一层就行,更新多了没用(如果更新到底,就变成单点更新了,复杂度爆炸)
代码如下:
#include <cstdio>
#include <algorithm> using namespace std;
#define M 100005
struct segTree
{
int l,r;
long long int sum,add;
int mid()
{
return (l+r)>>;
}
}tree[M<<];
int n,m;
void PushUp (int now)//向上更新:当前节点的sum等于其左右儿子的sum的和
{
tree[now].sum=tree[now<<].sum+tree[now<<|].sum;
}
void buildTree (int now,int l,int r)
{
tree[now].l=l,tree[now].r=r;
tree[now].add=;
if (l==r)
{
scanf("%lld",&tree[now].sum);
return;
}
int m=tree[now].mid();
buildTree(now<<,l,m);//递归建树
buildTree(now<<|,m+,r);
PushUp(now);//向上更新
}
void PushDown (int now,int m)
//向下更新:当前节点的add值需要加到自己左右儿子的add与sum上
{
if (tree[now].add)
{
tree[now<<].add+=tree[now].add;
tree[now<<|].add+=tree[now].add;
tree[now<<].sum+=tree[now].add*(m-(m>>));
tree[now<<|].sum+=tree[now].add*(m>>);
tree[now].add=;
}
}
void UpDate (int now,int l,int r,int change)
//区间[l,r]需要增加值change,now是当前节点
{
if (tree[now].l==l&&r==tree[now].r)
//如果恰好now代表的区间就是更新的区间,一步更新,暂不向下继续更新到其子节点 ,等用到这个节点再向下更新
{
tree[now].add+=change;
tree[now].sum+=(__int64)change*(r-l+);
return ;
}
if (tree[now].l==tree[now].r)
return;//区间长度为1,return
PushDown(now,tree[now].r-tree[now].l+);
//用到了当前节点,当前节点向下更新
int m=tree[now].mid();
if (r<=m)
//==============|==============tree[now]的区间
// ******** 要更新的区间
UpDate(now<<,l,r,change);
else if (l>m)
//==============|==============tree[now]的区间
// ******** 要更新的区间
UpDate(now<<|,l,r,change);
else
//==============|==============tree[now]的区间
// ************* 要更新的区间
{
UpDate(now<<,l,m,change);
UpDate(now<<|,m+,r,change);
}
PushUp(now);
}
long long int query (int now,int l,int r)
{
if(l==tree[now].l &&r==tree[now].r)
{
return tree[now].sum;
}
PushDown(now,tree[now].r-tree[now].l+);//用到了当前节点,向下更新
int m = tree[now].mid();
long long int res = ;
if(r<=m)
//==============|==============tree[now]的区间
// ******** 要查询的区间
res += query(now<<,l,r);
else if(l > m)
//==============|==============tree[now]的区间
// ******** 要查询的区间
res += query(now<<|,l,r);
//==============|==============tree[now]的区间
// ************* 要更新的区间
else
{
res+=query(now<<,l,m);
res+=query(now<<|,m+,r);
}
return res;
}
int main()
{
//freopen("de.txt","r",stdin);
while (~scanf("%d%d",&n,&m))
{
buildTree(,,n);
while (m--)
{
char op[];
scanf("%s",op);
int x,y,z;
if (op[]=='Q')
{
scanf("%d%d",&x,&y);
printf("%lld\n",query(,x,y));
}
else
{
scanf("%d%d%d",&x,&y,&z);
UpDate(,x,y,z);
}
}
}
return ;
}
POJ 3468 A Simple Problem with Integers(线段树区间修改及查询)的更多相关文章
- POJ 3468 A Simple Problem with Integers 线段树区间修改
http://poj.org/problem?id=3468 题目大意: 给你N个数还有Q组操作(1 ≤ N,Q ≤ 100000) 操作分为两种,Q A B 表示输出[A,B]的和 C A B ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal ...
- poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 75541 ...
- poj 3468 A Simple Problem with Integers 线段树区间更新
id=3468">点击打开链接题目链接 A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072 ...
- POJ 3468 A Simple Problem with Integers(线段树,区间更新,区间求和)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 67511 ...
- (简单) POJ 3468 A Simple Problem with Integers , 线段树+区间更新。
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(线段树区间更新)
题目地址:POJ 3468 打了个篮球回来果然神经有点冲动. . 无脑的狂交了8次WA..竟然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题. 区间更新就是加一个lazy标记,延迟标记, ...
- POJ 3468 A Simple Problem with Integers(线段树区间更新,模板题,求区间和)
#include <iostream> #include <stdio.h> #include <string.h> #define lson rt<< ...
随机推荐
- window安装activemq
原文: https://www.cnblogs.com/donsenChen/p/8656563.html ActiveMQ5.14.5下载地址 http://activemq.apache.org/ ...
- [CSP-S模拟测试]:字符消除2(hash+KMP)
题目背景 生牛哥终于打通了“字符消除”,可是他又被它的续集难倒了. 题目传送门(内部题52) 输入格式 第一行$n$表示数据组书.接下来每行一个字符串.(只包含大写字母) 输出格式 每组数据输出一个$ ...
- 使用selenium+BeautifulSoup 抓取京东商城手机信息
1.准备工作: chromedriver 传送门:国内:http://npm.taobao.org/mirrors/chromedriver/ vpn: selenium BeautifulSo ...
- spring cloud gateway 拦截request Body
在接入Spring-Cloud-Gateway时,可能有需求进行缓存Json-Body数据或者Form-Urlencoded数据的情况. 由于Spring-Cloud-Gateway是以WebFlux ...
- Git 提交的正确姿势
Git 提交的正确姿势:Commit message 编写指南 SCOP范围 middleware core config plugin test type范围 Git 每次提交代码,都要写 Comm ...
- Python 多进程异常处理
前言 最近项目用到了Python作为网站的前端,使用的框架是基于线程池的Cherrypy,但是前端依然有一些比较‘重’的模块.由于python的多线程无法很好的利用多核的性质,所以觉得把这些比较‘重’ ...
- JQuery实现页面跳转
$(function(){ var pn = $("#gotopagenum").val(); //#gotopagenum是文本框的id属性 location.hre ...
- Cocos2d-x之Menu
| 版权声明:本文为博主原创文章,未经博主允许不得转载. cocos2d-x菜单简介: 菜单也是游戏开发中的重要环节,一般游戏开始的第一个画面都是游戏主菜单,这些菜单包括,开始游戏,游戏设置,关卡 ...
- Java开发用H2数据库
#JPA Configuration:#spring.jpa.database=MySQLspring.datasource.url=jdbc:h2:mem:jpaspring.datasource. ...
- 为什么要使用MQ和到底什么时候要使用MQ
一.缘起 一切脱离业务的架构设计与新技术引入都是耍流氓. 引入一个技术之前,首先应该解答的问题是,这个技术解决什么问题. 就像微服务分层架构之前,应该首先回答,为什么要引入微服务,微服务究竟解决什 ...