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<< ...
随机推荐
- Oracle or Question Solve(一)
Oracle查看版本命令:select * from v$version; ORACLE_BASE和ORACLE_HOME路径查看su - oracleecho $ORACLE_BASEecho $O ...
- 杂项-报表-Minitab:Minitab百科
ylbtech-杂项-报表-Minitab:Minitab百科 Minitab软件是现代质量管理统计的领先者,全球六西格玛实施的共同语言,以无可比拟的强大功能和简易的可视化操作深受广大质量学者和统计专 ...
- Hibernate中常用HQL
HQL是Hibernate自带的查询语言 HQL是一种面向对象的查询语言.SQL的操作对象是数据表和列等数据对象,而HQL的操作对象是类.实例.属性等. HQL的语法很像SQL的语法 以下举例均以学生 ...
- build temu error about SDL
1. 安装sdl2 sudo apt-get install libsdl2-dev 2. 将configure文件中与SDL有关的地方改成SDL2 if test -z "$sdl&quo ...
- upc组队赛15 Supreme Number【打表】
Supreme Number 题目链接 题目描述 A prime number (or a prime) is a natural number greater than 1 that cannot ...
- tensorflow队列tf.FIFOQueue | enqueue | enqueue_many | dequeue | dequeue_many
关于队列的相关知识,盗用一张https://blog.csdn.net/HowardWood/article/details/79406891的动态图 import tensorflow as tf ...
- MSF——Meterpreter(三)
MSF系列: MSF——基本使用和Exploit模块(一) MSF——Payload模块(二) MSF——Meterpreter(三) MSF——信息收集(四) 一.简介 Meterpreter是Me ...
- c++实现哈夫曼树,哈夫曼编码,哈夫曼解码(字符串去重,并统计频率)
#include <iostream> #include <iomanip> #include <string> #include <cstdlib> ...
- 领域驱动设计(DDD:Domain-Driven Design) 转摘自:http://www.jdon.com/ddd.html
Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD ...
- 六、hibernate表与表之间的关系(多对多关系)
多对多关系 创建实体类和对应映射文件 Student.java package com.qf.entity; import java.util.HashSet; import java.util.Se ...