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<< ...
随机推荐
- CSP-S2019退役记/爆内存记
DAY 0 准备出发. 出发前教练说遇到事不慌,打电话,又听教练说了说历年赶车经历. 然后这趟路上居然没有什么大事. 在车上有些闲,于是就和其他人聊了会天,聊着聊着没意思,就用手机翻博客园. 这样就不 ...
- AcWing 313. 花店橱窗 (线性DP)打卡
题目:https://www.acwing.com/problem/content/315/ 题意:有一个矩阵,你需要在每一行选择一个数,必须保证前一行的数的下标选择在下一行的左边,即下标有单调性,然 ...
- html中ul,ol和li的区别
ul是无序列表,全称是unordered list,先来个例子: ●张三 ●李四 ●王二 ●刘五 ol是有序列表 ,全称是ordered list,同样举个例子: 1.张 ...
- php面试专题---2、常量及数据类型考点
php面试专题---2.常量及数据类型考点 一.总结 一句话总结: 变量为null和变量判断为false的情况需要仔细注意下 1.PHP中字符串可以使用哪三种定义方法以及各自的区别是什么? 单引号:不 ...
- kaggle-制作评分卡
https://blog.csdn.net/zpxcod007/article/details/80118580 制作A卡,申请评分卡 数据集:15万个样本,特征 主要预处理手段:缺失值,异常值,样本 ...
- 继承Process类,run函数的简单使用
#定义一个类 继承Process类 from multiprocessing import Process import os import time class Download(Process): ...
- win10 命令重置 管理员密码
重置win10系统管理员的方法有不少,这里给大家介绍的一种用Windows PowerShell命令重置win10管理员密码方法教程,感兴趣的用户,可以学习一下. 操作过程: 1.点击左下角的开始菜单 ...
- lr 计算字符串长度
sizeof求后面的内容or表达式所占用的字节数 strlen求字符串的有效长度,只要遇到'\0'就认为字符串结束 字符串转化为int型变量 Action2() { int j = 0; j = at ...
- luoguP1079 Vigenère 密码 题解(NOIP2012)
P1079 Vigenère 密码 题目 #include<iostream> #include<cstdlib> #include<cstdio> #includ ...
- SSOJ 317 Fast Ride
317. Fast Ride Time limit per test: 0.25 second(s) Memory limit: 65536 kilobytes input: standard ou ...