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(线段树区间修改及查询)的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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 ...

  4. [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]

    A Simple Problem with Integers   Description You have N integers, A1, A2, ... , AN. You need to deal ...

  5. poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 75541   ...

  6. poj 3468 A Simple Problem with Integers 线段树区间更新

    id=3468">点击打开链接题目链接 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072 ...

  7. POJ 3468 A Simple Problem with Integers(线段树,区间更新,区间求和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 67511   ...

  8. (简单) 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 ...

  9. POJ 3468 A Simple Problem with Integers(线段树区间更新)

    题目地址:POJ 3468 打了个篮球回来果然神经有点冲动. . 无脑的狂交了8次WA..竟然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题. 区间更新就是加一个lazy标记,延迟标记, ...

  10. POJ 3468 A Simple Problem with Integers(线段树区间更新,模板题,求区间和)

    #include <iostream> #include <stdio.h> #include <string.h> #define lson rt<< ...

随机推荐

  1. delphi 程序嵌入桌面效果的实现

    function Tform1.CreateRegion(wMask:TBitmap;wColor:TColor;hControl:THandle): HRGN; var dc, dc_c: HDC; ...

  2. CMMI模型

    CMMI的成熟度级别 初始级(过程不可预测,管理和控制差,是反应式的)管理级(过程处于项目级,经常是反应式的)定义级(过程已经提升到组织级(OSSP))定量管理级(对过程进行度量,并进行统计控制)优化 ...

  3. LOJ 3093 「BJOI2019」光线——数学+思路

    题目:https://loj.ac/problem/3093 考虑经过种种反射,最终射下去的光线总和.往下的光线就是这个总和 * a[ i ] . 比如只有两层的话,设射到第二层的光线是 lst ,那 ...

  4. php读取excel(支持03,07)

    需要用到PHPExcel这个类 附上代码 //phpExcel读取excel内容 header("Content-Type:textml;charset=utf-8"); //引用 ...

  5. 【转】 Linux 命令解释(Linux基础二)

    前言 对服务器来讲,图形界面会占用更多的系统资源,而且会安装更多的服务.开放更多的端口,这对服务器的稳定性和安全性都有负面影响.其实,服务器是一个连显示器都没有的家伙,要图形界面干十么? 说到这里,有 ...

  6. 杂项-网络-DNS-IP:8.8.8.8

    ylbtech-杂项-网络-DNS-IP:8.8.8.8 8.8.8.8是一个IP地址,是Google提供的免费DNS服务器的IP地址,Google提供的另外一个免费DNS服务器的IP地址是:8.8. ...

  7. springboot 导出excel

    依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</ ...

  8. 用 Flask 来写个轻博客 (20) — 实现注册表单与应用 reCAPTCHA 来实现验证码

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 reCAPTCHA 应用 reCAPTCHA 前文列表 用 Flask ...

  9. iview+vue 使用中遇到的问题(表格、select、radio)

    1.iview+vue中,对表头的动态设置: iview表头若是需要动态设置,可以有两个方法,第一种: children: [ { title: '2017年', align: 'center', k ...

  10. 小程序UI自动化(一):appium小程序自动化尝试

    appium 进行 小程序自动化尝试: 由于工作中进行app自动化用的是appium,故首先尝试用appium进行小程序自动化,以美团小程序为例(python脚本实现) 一.配置基础信息 启动微信ap ...