【模板】树状数组 1

题目描述

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

  • 将某一个数加上 x

  • 求出某区间每一个数的和

输入格式

第一行包含两个正整数 n,m ,分别表示该数列数字的个数和操作的总个数。

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

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

  • 1 x k 含义:将第 x 个数加上 k

  • 2 x y 含义:输出区间 [x,y] 内每个数的和

输出格式

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

样例 #1

样例输入 #1

5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4

样例输出 #1

14
16

提示

【数据范围】

对于 30% 的数据,1 ≤ n ≤ 8$1 ≤ m ≤ 10

对于 70% 的数据,1 ≤ n,m ≤ 10^4

对于 100% 的数据,1 ≤ n,m ≤ 5 * 10^5

数据保证对于任意时刻,a 的任意子区间(包括长度为 1n 的子区间)和均在 [-2^{31}, 2^{31}) 范围内。

样例说明:

故输出结果14、16

思路:树状数组?线段树?

三步走!!!

  1. 建树

    void buildtree(int k,int l,int r){
    if(l==r){//l==r时就是分到只剩一个了
    f[k]=a[l];//此时返回叶子结点数据(也就是原数据)
    return;
    }
    //以下三步,就是找左右儿子
    //这个过程与归并排序的递归过程类似可以去看一下
    //其中2k和2k+1代表的是当前结点的左右子结点(这一步不详细展开,可以自己画图尝试)
    int mid=(l+r)>>1;
    buildtree(2*k,l,mid);
    buildtree(2*k+1,mid+1,r); //父亲结点=儿子结点的和
    f[k]=f[2*k]+f[2*k+1];
    }
  2. 修改数据

    void add(int k,int l,int r,int x,int y){//k表示第几个结点,l、r表示区间,x表示第几个值要修改,y表示要使原值+y
    //因为每次找到的都是第x个元素的父亲结点的父亲的父亲……所以直接+y
    f[k]+=y;//包含结点x的值都需要+y
    if(l==r) return;当递归到l=r即为只有一个元素返回
    int mid=(l+r)>>1;
    if(x<=mid) add(2*k,l,mid,x,y);如果是在左子树就往左找
    else add(2*k+1,mid+1,r,x,y);如果是在右子树就往右边找 }
  3. 计算答案

    int calc(int k,int l,int r,int s,int t){//s、t表示要求的区间反围
    if(l==s && r==t)//如果区间缩小到包含原数据区间的子区间反围即返回
    return f[k];
    int mid=(l+r)>>1;
    if(t<=mid)
    return calc(2*k,l,mid,s,t);//如果当前要求的区间范围在左子树就往左边找
    else//在右子树或者部分在右子树
    if(s>mid)
    return calc(2*k+1,mid+1,r,s,t);//在右子树上
    else
    return calc(2*k,l,mid,s,mid)+calc(2*k+1,mid+1,r,mid+1,t);//部分在右子树
    }

tips:这个树状数组应该开多大?

开4n。参考证明连接:线段树需要开4倍区间大小的数组的原因_线段树数组一般开 n*4 的大小-CSDN博客

(本文章仅供学习交流如有侵权请私信立刻删除)

AC Code

// Problem:
// P3374 【模板】树状数组 1
//
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3374
// Memory Limit: 512 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org) #include<iostream>
#include<algorithm>
//#include<cstdio> #define ll long long
#define endl '\n'
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>(b);i--)
#define N 2000100 //1e6+100
#define M 500010
using namespace std;
int f[N],a[M],n,m;
void buildtree(int k,int l,int r){
if(l==r){
f[k]=a[l];
return;
}
int mid=(l+r)>>1;
buildtree(2*k,l,mid);
buildtree(2*k+1,mid+1,r);
f[k]=f[2*k]+f[2*k+1];
}
void add(int k,int l,int r,int x,int y){
f[k]+=y;
if(l==r) return;
int mid=(l+r)>>1;
if(x<=mid) add(2*k,l,mid,x,y);
else add(2*k+1,mid+1,r,x,y);
}
int calc(int k,int l,int r,int s,int t){
if(l==s && r==t)
return f[k];
int mid=(l+r)>>1;
if(t<=mid)
return calc(2*k,l,mid,s,t);
else
if(s>mid)
return calc(2*k+1,mid+1,r,s,t);
else
return calc(2*k,l,mid,s,mid)+calc(2*k+1,mid+1,r,mid+1,t);
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>m;
rep(i,1,n)
cin>>a[i];
buildtree(1,1,n);
int t,x,y;
while(m--){
cin>>t>>x>>y;
if(t==1)
add(1,1,n,x,y);
else cout<<calc(1,1,n,x,y)<<endl;;
}
return 0;
}

P3374 【模板】树状数组 1(线段树)的更多相关文章

  1. st表、树状数组与线段树 笔记与思路整理

    已更新(2/3):st表.树状数组 st表.树状数组与线段树是三种比较高级的数据结构,大多数操作时间复杂度为O(log n),用来处理一些RMQ问题或类似的数列区间处理问题. 一.ST表(Sparse ...

  2. bzoj3196 二逼平衡树 树状数组套线段树

    题目传送门 思路:树状数组套线段树模板题. 什么是树状数组套线段树,普通的树状数组每个点都是一个权值,而这里的树状数组每个点都是一颗权值线段树,我们用前缀差分的方法求得每个区间的各种信息, 其实关键就 ...

  3. 2019南昌网络赛  I. Yukino With Subinterval 树状数组套线段树

    I. Yukino With Subinterval 题目链接: Problem Descripe Yukino has an array \(a_1, a_2 \cdots a_n\). As a ...

  4. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  5. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

  6. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  7. POJ 1195 Mobile phones (二维树状数组或线段树)

    偶然发现这题还没A掉............速速解决了............. 树状数组和线段树比较下,线段树是在是太冗余了,以后能用树状数组还是尽量用......... #include < ...

  8. 【BZOJ3196】二逼平衡树(树状数组,线段树)

    [BZOJ3196]二逼平衡树(树状数组,线段树) 题面 BZOJ题面 题解 如果不存在区间修改操作: 搞一个权值线段树 区间第K大--->直接在线段树上二分 某个数第几大--->查询一下 ...

  9. BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...

  10. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

随机推荐

  1. [转帖]Linux 下rsync命令详细整理

    https://blog.csdn.net/weixin_44052462/article/details/116134761 rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面 ...

  2. [转帖]linux audit审计(7-1)--读懂audit日志

    https://www.cnblogs.com/xingmuxin/p/8807774.html  auid=0 auid记录Audit user ID,that is the loginuid.当我 ...

  3. [转帖]RAC环境下误操作将数据文件添加到本地存储

    https://www.cnblogs.com/jyzhao/p/7986729.html 今天碰到个有意思的事情,有客户在Oracle RAC环境,误操作将新增的数据文件直接创建到了其中一个节点的本 ...

  4. [转帖]global cache cr request等待事件分析及优化

    在RAC环境中,和全局调整缓存相关的最常见的等待事件无非就是:global cache cr request,global cache busy和equeue 在XX电信做了一次数据库巡检中发现,sp ...

  5. [转帖]Shell三剑客之awk

    目录 awk简述 awk的工作过程 awk的工作原理 awk的基本格式及其内置变量 getline 文本内容匹配过滤打印 对字段进行处理打印 条件判断打印 awk的三元表达式与精准筛选用法 awk的精 ...

  6. [转帖]Innodb存储引擎-锁(数据库锁的查看、快照读&当前读、MVCC、自增长与锁、外键与锁、行锁、并发事务的问题、阻塞、死锁、锁升级、锁的实现)

    文章目录 锁 lock 与latch 读锁/写锁/意向锁 INNODB_TRX/INNODB_LOCKS/INNODB_LOCK_WAITS 一致性非锁定读(快照读) 一致性锁定读(当前读) MVCC ...

  7. 小程序字节转GBK及UTF8

    前段时间在Android原生搞的BLE扫码枪又要移植到小程序上来.本以为小程序不支持BLE的,结果一搜,还真支持-_-|| . 蓝牙部分问题不大,遇到的主要问题是,小程序环境如何对字符编码进行判断以及 ...

  8. NLP涉及技术原理和应用简单讲解【一】:paddle(梯度裁剪、ONNX协议、动态图转静态图、推理部署)

    参考链接: https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/advanced/gradient_clip_cn.html 1. ...

  9. 【五】强化学习之Sarsa、Qlearing详细讲解----PaddlePaddlle【PARL】框架{飞桨}

    相关文章: [一]飞桨paddle[GPU.CPU]安装以及环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简 ...

  10. 【七】强化学习、gym学习平台扩充,更好的玩转虚拟环境,关于mujoco、mujoco-py、baselines安装配置

    相关文章: [一]gym环境安装以及安装遇到的错误解决 [二]gym初次入门一学就会-简明教程 [三]gym简单画图 [四]gym搭建自己的环境,全网最详细版本,3分钟你就学会了! [五]gym搭建自 ...