Description

You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+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

思路:

之前学了线段树单点更新,所以想都没想直接一个个点更新果断超时,然后发现是区间更新orz

这是道区间更新模板题。

线段树区间更新引入了一个新东西叫做“懒标记”,它的用处是当我们进行区间更新时不用更新到根节点,比如在[1,10]区间对[1,5]区间更新,我们不需要对1~5都更新(因为目前还没用到1~5),所以我们只要暂时把值存在[1,5]这个节点就行了。如果我们需要访问[1,5]的子节点时,我们需要将暂存的值往下加。

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<sstream>
#define ll long long
const int N=100005;
const int MOD=20071027;
using namespace std;
struct node{
int l,r;
ll num,add;
}node[N<<2];
int arr[N];
void build(int l,int r,int rt){
node[rt].l=l,
node[rt].r=r;
node[rt].add=0;
if(l==r){
node[rt].num=arr[l];
return;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
node[rt].num=node[rt<<1].num+node[rt<<1|1].num;
}
void add(int rt,int l,int r,int v){
if(node[rt].l==l && node[rt].r==r){ //暂时储存
node[rt].add+=v;
return;
}
node[rt].num+=v*(r-l+1);
int m=(node[rt].l+node[rt].r)>>1;
if(r<=m){ //改变区间属于左子节点子集
add(rt<<1,l,r,v);
}
else if(l>m){ //属于右子节点子集
add(rt<<1|1,l,r,v);
}
else{ //属于左右子节点子集
add(rt<<1,l,m,v);
add(rt<<1|1,m+1,r,v);
}
}
ll query(int rt,int l,int r){
if(node[rt].l==l && node[rt].r==r){
return node[rt].num+(r-l+1)*node[rt].add;
}
node[rt].num+=(node[rt].r-node[rt].l+1)*node[rt].add; //需要继续往下找,在这里加上之前暂时存放的值
int m=(node[rt].l+node[rt].r)>>1;
add(rt<<1,node[rt].l,m,node[rt].add);
add(rt<<1|1,m+1,node[rt].r,node[rt].add);
node[rt].add=0; //暂存值归零
if(r<=m){ //查询区间属于左子节点子集
return query(rt<<1,l,r);
}
else if(l>m){ //属于右子节点子集
return query(rt<<1|1,l,r);
}
else{ //属于左右子节点子集
return query(rt<<1,l,m)+query(rt<<1|1,m+1,r);
}
}
int main(){
int n,q,a,b,c;
ll ans;
char order[2];
while(scanf("%d%d",&n,&q)!=EOF){
for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
build(1,n,1);
while(q--){
scanf("%s",order);
if(order[0]=='Q'){
scanf("%d%d",&a,&b);
ans=query(1,a,b);
printf("%lld\n",ans);
}
else{
scanf("%d%d%d",&a,&b,&c);
add(1,a,b,c);
}
}
}
return 0;
}

POJ 3468 A Simple Problem with Integers(线段树&区间更新)题解的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. POJ 3468 A Simple Problem with Integers 线段树 区间更新

    #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #i ...

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

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

随机推荐

  1. windows kibana的连接使用

    下载后解压使用,打开config目录下的kibana.yml文件,然后添加:elasticsearch.url: "http://localhost:9200"  表示你要添加的e ...

  2. javaScript高级教程(二)Scope Chain & Closure Example

    <!DOCTYPE html> <html> <head> <meta charset=gb2312 /> <title>js</ti ...

  3. Dubbo简单环境搭建

    Dubbo服务的发展和作用: 首先,看下一般网站架构随着业务的发展,逻辑越来越复杂,数据量越来越大,交互越来越多之后的常规方案演进历程. 其次,当服务越来越多之后,我们需要做哪些服务治理? 最后,是d ...

  4. 第三课:JAVA反射机制

    基础的不想写啦,好了,直接上JAVA反射机制吧: 类对象概念: 所有的类,都存在一个类对象,这个类对象用于提供类层面的信息,比如有几种构造方法, 有多少属性,有哪些普通方法. JAVA类,他们的区别在 ...

  5. 常用python包(依赖)Ubuntu下

    amqp==1.4.9anyjson==0.3.3apturl==0.5.2beautifulsoup4==4.4.1billiard==3.3.0.23blinker==1.3Brlapi==0.6 ...

  6. vue学习之六路由系统

    一.vueRouter实现原理 VueRouter的实现原理是根据监控锚点值的改变,从而不断修改组件内容来实现的,我们来试试不使用VueRouter,自己实现路由控制,如下代码: <!DOCTY ...

  7. [LeetCode] 312. Burst Balloons_hard tag: 区间Dynamic Programming

    Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...

  8. 4.keras实现-->生成式深度学习之DeepDream

    DeepDream是一种艺术性的图像修改技术,它用到了卷积神经网络学到的表示,DeepDream由Google于2015年发布.这个算法与卷积神经网络过滤器可视化技术几乎相同,都是反向运行一个卷积神经 ...

  9. 机器学习 python库 介绍

    开源机器学习库介绍 MLlib in Apache Spark:Spark下的分布式机器学习库.官网 scikit-learn:基于SciPy的机器学习模块.官网 LibRec:一个专注于推荐算法的j ...

  10. Fuzzy and fun on Air Jordan 12 Doernbecher design

    Carissa Navarro keeps it warm, fuzzy and fun on her 2017 Air Jordan 12 Doernbecher design. Nike's 20 ...