如题,已知一个数列,你需要进行下面两种操作:

1.将某区间每一个数加上x

2.求出某区间每一个数的和

输入格式

第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

输出格式

输出包含若干行整数,即为所有操作2的结果。

输入输出样例

输入 #1复制

5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
输出 #1复制

11
8
20

说明/提示

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=1000,M<=10000

对于100%的数据:N<=100000,M<=100000

(数据已经过加强^_^,保证在int64/long long数据范围内)

样例说明:

 #include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<string>
#include<algorithm>
#include<iomanip>
using namespace std;
const int maxn = ;
int arr[maxn +];
struct node
{
/* data */
long long value;//该结点维护的值
int left;
int right;
long long add;//lazy 每个区间的增量
}tree[maxn* + ]; inline void PushUp(int root)
{
tree[root].value = tree[root <<].value + tree[root<<|].value;
} void Build(int root,int x,int y)
{
tree[root].left = x;
tree[root].right = y;
if(x == y)
{
tree[root].value = arr[x];
return ;
}
int mid = (x + y) >> ;
Build(root<<, x,mid);
Build(root<<|,mid+,y);
PushUp(root);
} void Spread(int root)//懒标记
{
if(tree[root].add)//如果树根结点的懒标记不为0 ,修改左右儿子的值
{
tree[root<<].value += tree[root].add * (tree[root<<].right - tree[root<<].left +);
tree[root<<|].value += tree[root].add * (tree[root<<|].right - tree[root<<|].left +);
//左右儿子的值增加为父亲结点的增量乘以自己各区间的长度
tree[root<<].add += tree[root].add;
tree[root<<|].add += tree[root].add;
tree[root].add = ;//父亲结点增量变为0;
}
}
void Change(int root,int x,int y,int z)//给根结点为root 区间为(x,y)的每个值加上z
{
if( x <= tree[root].left && y >= tree[root].right)//区间被完全覆盖
{
tree[root].value += (long long )z * (tree[root].right - tree[root].left + );
tree[root].add += z;
return ;
}
Spread(root);//如果没有发现区间被覆盖,即需要继续向下找,并把懒标记下放
int mid = (tree[root].right + tree[root].left) >> ;
if( x <= mid)//要修还区间覆盖了左儿子,修改
{
Change(root<<,x,y,z);
}
if( y > mid)//右儿子同理
{
Change(root<<|,x,y,z);
}
PushUp(root);
} long long Query(int root,int x,int y)//对区间(x,y)的查询操作
{
long long ans = ;
if( x <= tree[root].left && y >= tree[root].right )//查询区间被根结点所对应区间覆盖
{
return tree[root].value;
}
Spread(root);//下传懒标记
int mid = (tree[root].left + tree[root].right) >> ;
if ( x <= mid)
{
ans += Query(root<<,x,y);
}
if( y > mid)
{
ans += Query(root<<|,x,y);
}
return ans;
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = ; i<= n;i++)
{
scanf("%d",&arr[i]);
}
Build(,,n);
for(int i = ;i < m;i++)
{
int flag;
int x,y,k;
cin>>flag;
if(flag == )
{
scanf("%d%d%d",&x,&y,&k);
Change(,x,y,k);
}
else
{
scanf("%d%d",&x,&y);
cout<<Query(,x,y)<<endl;
}
}
return ;
}

洛谷P3372--线段树代码模板1的更多相关文章

  1. 洛谷P3372线段树模板1——线段树

    题目:https://www.luogu.org/problemnew/show/P3372 线段树模板. 代码如下: #include<iostream> #include<cst ...

  2. 洛谷P3372线段树1

    难以平复鸡冻的心情,虽然可能在大佬眼里这是水题,但对蒟蒻的我来说这是个巨大的突破(谢谢我最亲爱的lp陪我写完,给我力量).网上关于线段树的题解都很玄学,包括李煜东的<算法竞赛进阶指南>中的 ...

  3. 洛谷 P3372 线段树1

    这是一道模板题 线段树介绍https://www.cnblogs.com/nvwang123/p/10420832.html #include<bits/stdc++.h> using n ...

  4. NOIP2017提高组Day2T3 列队 洛谷P3960 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/9265380.html 题目传送门 - 洛谷P3960 题目传送门 - LOJ#2319 题目传送门 - Vij ...

  5. 洛谷P3373线段树模板2

    题目:https://www.luogu.org/problemnew/show/P3373 带乘的线段树,更新时把加的标记也乘一下,然后取值时先乘后加. 代码如下: #include<iost ...

  6. 洛谷P3373 线段树2(补上注释了)

    毒瘤题.找了一下午+晚上的BUG,才发现原来query_tree写的是a%p; 真的是一个教训 UPD:2019.6.18 #include<iostream> #include<c ...

  7. 洛谷3372线段树模板题 对区间+k或者查询区间和

    #include<bits/stdc++.h> using namespace std; typedef unsigned int ui; typedef long long ll; ty ...

  8. 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)

    洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...

  9. 洛谷1087 FBI树 解题报告

    洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...

随机推荐

  1. SpringCloud-Eureka配置instanceId显示IP

    eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: preferIpAddress: tr ...

  2. typescript类 继承 修饰符

    //1.ts中类的定义 /* es5: function Person(name){ this.name=name; this.run=function(){ console.log(this.nam ...

  3. 我非要捅穿这 Neutron(二)上层资源模型篇

    目录 文章目录 目录 Neutron 的资源模型 Network 运营商网络和租户网络 创建运营商网络 创建租户网络 创建外部网络 Network 小结 Subnet IP 核心网络服务 Subnet ...

  4. linux中导入sql文件

    在linux中导入sql文件的方法分享(使用命令行转移mysql数据库) 因导出sql文件 在你原来的网站服务商处利用phpmyadmin导出数据库为sql文件,这个步骤大家都会,不赘述. 上传sql ...

  5. 使用 Ninja 代替 make

    使用 Ninja 代替 make 摘自:https://www.jianshu.com/p/d118615c1943 22017.01.14 11:41:44字数 1408阅读 26336 前言 在传 ...

  6. [译]如何在GitHub仓库创建一个标签tag, 并推送到远程分支?

    问: 我在GitHub上有一个仓库,我需要给他打个tag.我在shell打了tag,但是在Github上没有显示出来.我还要做其他什么么? 我在shell中使用的命令是: git tag 2.0 当我 ...

  7. Qt编写自定义控件64-垂直时间轴

    一.前言 垂直时间轴控件,主要用来描述企业发展历程大事件,或者软件版本迭代历史等,通过时间节点和事件描述来直观的展示发展的过程,一般在web网页或者app中经常看到此类控件,尤其是公司的官网关于公司部 ...

  8. 123457123456#0#-----com.cym.shuXue02--前拼后广--开心学数学

    com.cym.shuXue02--前拼后广--开心学数学

  9. WebSocket接收音频,并推送到声卡上

    使用信息 import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableM ...

  10. kubernetes&prometheus 【组件】

    查看prometheus target页面可得组件 kube-state-metric: https://github.com/kubernetes/kube-state-metrics/blob/m ...