题目描述

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

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 <cstdio>
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
using namespace std;#define ll long long
#define eps 1e-9const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;ll n, m, a[1000000+8], ans;struct node
{ll left, right, sum, lz;
}tree[1000000+8];void build(ll left, ll right, ll i)///建树
{tree[i].lz = 0;///懒惰标记初始化为0tree[i].left = left;tree[i].right = right;if(left == right)///如果已经是叶子结点
    {tree[i].sum = a[left];return ;}ll mid = (right+left)/2;build(left, mid, i*2);///往左边的区间进行建树build(mid+1, right, i*2+1);///往右边的区间进行建树tree[i].sum = tree[i*2].sum+tree[i*2+1].sum;///自己的和等于左儿子和右儿子的和
}void push_down(ll i)///把自己的lazytage归零,并给自己的儿子加上,并让自己的儿子加上k*(r-l+1)
{if(tree[i].lz != 0)///如果这个点已经被标记了
    {tree[i*2].lz += tree[i].lz;///左儿子的懒惰标记等于父亲的懒惰标记tree[i*2+1].lz += tree[i].lz;///右儿子的懒惰标记等于父亲的懒惰标记ll mid = (tree[i].left+tree[i].right)/2;tree[i*2].sum += tree[i].lz*(mid-tree[i*2].left +1);///左儿子的和等于它所控制的区间的和tree[i*2+1].sum += tree[i].lz*(tree[i*2+1].right-mid);///右儿子的和等于它所控制的区间的和tree[i].lz = 0;///父节点懒惰标记归零
    }return ;
}void pls(ll i, ll l, ll r, ll k)///区间加
{if(tree[i].right <= r && tree[i].left >= l)///如果这个区间就在目标区间的内部
    {tree[i].sum += k*(tree[i].right-tree[i].left+1);///这个区间的和  等于(这个区间原本的和)+(k*这个区间的元素个数)tree[i].lz += k;///懒惰标记,表示它已经加了kreturn ;}push_down(i);///把自己的lazytage归零,并给自己的儿子加上,并让自己的儿子加上k*(r-l+1)if(tree[i*2].right >= l)///如果这个区间与左边部分区间重叠,就往左边区间每个元素加上kpls(i*2, l, r, k);if(tree[i*2+1].left <= r)///如果这个区间与右边部分区间重叠,就往右边区间每个元素加上kpls(i*2+1, l, r, k);tree[i].sum = tree[i*2].sum+tree[i*2+1].sum;///父节点的和等于左儿子的和加右儿子的和return ;
}void search(ll i, ll l, ll r)///查找区间和
{if(tree[i].left >= l && tree[i].right <= r)///如果这个区间就在目标区间的内部
    {ans += tree[i].sum;return ;}if(tree[i].lz)push_down(i);///一层一层的进行标记,方便后来的查找区间和ll mid = (tree[i].left+tree[i].right)/2;if(l <= mid)///如果这个区间与左边部分区间重叠,就 ans + 左边区间每个元素加上ksearch(i*2, l, r);if(mid<r)///如果这个区间与右边部分区间重叠,就 ans + 右边区间每个元素加上ksearch(i*2+1, l, r);
}int main()
{scanf("%lld%lld", &n, &m);for(ll i = 1; i <= n; i++)scanf("%lld", &a[i]);build(1, n, 1);///初始化线段树for(ll i = 1; i <= m; i++){ll f;scanf("%lld", &f);if(f == 1){ll x, y, z;scanf("%lld%lld%lld", &x, &y, &z);pls(1, x, y, z);///从根节点开始进行区间加c
        }else if(f == 2){ll x, y;scanf("%lld%lld", &x, &y);ans = 0;search(1, x, y);printf("%lld\n", ans);///输出区间[a, b]的值
        }}return 0;
}

转载于:https://www.cnblogs.com/RootVount/p/11285251.html

洛谷 P3372 【模板】线段树 1(线段树区间加区间找)相关推荐

  1. 线段树动态开点区间加区间求和

    线段树动态开点区间加区间求和 题目来源: 陕西师范大学第七届程序设计竞赛网络同步赛 H. 万恶的柯怡 思想: 保证叶子节点被完整的覆盖,需要开节点,就把左右儿子都开出来,其余和普通线段树一样. tip ...

  2. 洛谷 p3372 模板-线段树 1

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个 ...

  3. 洛谷 - P1886 滑动窗口(单调队列/线段树)

    题目链接:点击查看 题目大意:给出一个由n个数构成的序列,再给出一个长度为k的窗口,这个窗口从第一个下标开始一直向后移动,每次移动一个单位,每次移动询问一次该窗口中的最大值和最小值,最后输出答案 题目 ...

  4. 【题解】洛谷P4145 花神游历各国(线段树)

    洛谷P4145:https://www.luogu.org/problemnew/show/P4145 思路 这道题的重点在于sqrt(1)=1 一个限制条件 与正常线段树不同的是区间修改为开方 那么 ...

  5. 专题·树链剖分【including 洛谷·【模板】树链剖分

    初见安~~~终于学会了树剖~~~ [兴奋]当初机房的大佬在学树剖的时候我反复强调过:"学树剖没有前途的!!!" 恩.真香. 一.重链与重儿子 所谓树剖--树链剖分,就是赋予一个链的 ...

  6. 洛谷·【模板】点分树 | 震波【including 点分树

    初见安-这里是传送门:洛谷P6329 [模板]点分树 | 震波 一.点分树 其实你会点分治的话,点分树就是把点分治时的重心提出来重新连城一棵树. 比如当前点是u,求出子树v的重心root后将root与 ...

  7. ⌈洛谷1505⌋⌈BZOJ2157⌋⌈国家集训队⌋旅游【树链剖分】

    题目链接 [洛谷] [BZOJ] 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T ...

  8. 【JZOJ3794】【洛谷P1383】高级打字机【主席树】

    题目大意: 题目链接: 洛谷:https://www.luogu.org/problemnew/show/P1383 JZOJ:https://jzoj.net/senior/#main/show/3 ...

  9. 洛谷 P3372 【模板】线段树 1

    文章目录 题目描述 输入格式 输出格式 输入输出样例 说明 [样例解释] AC的C++代码(结合注释理解) 题目描述 如题,已知一个数列,你需要进行下面两种操作: 将某区间每一个数加上k. 求出某区间 ...

最新文章

  1. sed 格式化输出df -h
  2. 新建swap分区的规划、挂载和自动挂载示例
  3. shell 获取 mysql 行数_一个Shell小脚本精准统计Mysql每张表的行数实现
  4. P4 前端编译器p4c-bm、后端编译器bmv2命令安装 make error问题
  5. 【渝粤教育】电大中专会计电算化 (2)作业 题库
  6. Linux异步IO实现方案总结
  7. Trick(四)——翻转字符串的实现
  8. 真·不怪云原生:探寻IT大厂逐渐云化的秘密!
  9. Debian9用户态下安装pipenv
  10. 系统架构设计-计算机组成与体系结构
  11. 64位plsql和64位Oracle客户端安装以及注册,内含百度云资源
  12. 编写一个以C 语言为基础的DSP程序
  13. ENVI剪裁图片( 剪裁、裁移位等问题)
  14. 微信朋友圈 腾讯服务器,朋友圈@微信能得一面红旗?腾讯服务器一度宕机
  15. 高等数学——驻点,拐点,极值点
  16. 在日冕病毒时代的爱情-远程工作的技巧,窍门和最佳实践
  17. 如何申请屏蔽垃圾短信
  18. 一步一步构建手机WebApp开发——页面布局篇
  19. DSP技术是利用计算机或,DSP技术综述1
  20. 2020中北大学计算机调剂名额,2020年中北大学考研调剂安排

热门文章

  1. 第三章:Creating Utilities--27.增加一个本地词典
  2. xaml中的布局面板
  3. Cordova/Ionic Android 开发环境搭建 - Windows系统
  4. mysql 使用正则表达式查询
  5. 【laravel5.4 + TP5.0】hasOne和belongsTo的区别
  6. 2017-12-04HTML布局_div布局
  7. 给vmstat加上时间戳
  8. Linux下文件的三个时间意义及用法
  9. python 类的功能,字符串字节,嵌套等相关学习总结
  10. BlendMode类