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<< ...
随机推荐
- python之字符串切分
在工作中,经常遇到字符串切分,尤其是操作linux命令,返回一段文本,如下面这种格式 Filesystem Size Used Avail Use% Mounted on /dev/vda1 40G ...
- sql 2008常用语法语句收集
EXEC sp_dropuser 'test' : 从当前数据库删除用户 test EXEC sp_droplogin 'test' : 从 SQL Server 中删除登录 test select ...
- window环境下pipd的安装
参照:https://blog.csdn.net/jin80506/article/details/83111848 如果你还是无法使用尝试查看是否自己已经将:C:\software\Python\P ...
- MVC 入门
MVC是什么? MVC是一个框架模式,它用于把应用程序的输入.处理和输出进行强制性的分开.使用MVC应用程序被分成三个核心部件:模型.视图.控制器.它们各自处理自己的任务.最典型的MVC就是JSP+S ...
- [题解]Magic Line-计算几何(2019牛客多校第三场H题)
题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意: 给你偶数个点的坐标,找出一条直线将这n个点分成数量相等的两部分 并在这条直线上取不同的两个点,表示 ...
- MFC绘图基础
·MFC中三种坐标系统: 1.屏幕坐标系 坐标原点位于屏幕左上角 2.(非客户区)窗口坐标系 坐标原点位于窗口左上角(包括标题栏) 3.客户区坐标系 坐标原点位于客户区左上角(不包括标题栏) ·坐标系 ...
- spring cloud学习--eureka 01
本博客为学习使用,学习教程翟永超 spring cloud 微服务实战 搭建eureka server注册中心 spring initialize构建spring boot项目 构建网址:https: ...
- inno setup静默安装
[Code] //关键代码静默安装 procedure InitializeWizard(); begin //不显示边框,这样就能达到不会闪两下了 WizardForm.BorderStyl ...
- ThinkPHP3.2.3 目录介绍
ThinkPHP3.2.3 目录介绍,在开发中主要操作的目录就是在入口文件www/index.php中定义的www/application/文件目录了. www WEB部署目录 ├─index.ph ...
- Oracle学习笔记<6>
建表 1.建表语句语法 create table [schema.]table_name( 字段名 字段类型 [默认值] [列级约束], 字段名 字段类型 [默认值] [列级约束], 字段名 字段类型 ...