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

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

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

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

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

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

输入输出样例
输入:
5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4
输出:
14
16

提示:
对于100%的数据,1≤n,m≤5×10^5

分析:首先可以知道最暴力的求解方法的复杂度是O(mn),对于100%的数据是必然超时的,因此引入了线段树:

对于一个区间[1,n]的数,我们可以做出一个二叉树的模型,根结点就是区间[1,n]这个线段,那么其左孩子和右孩子分别就是[1,n/2]和[n/2+1,n],依次类推,直到线段(结点)就是一个点为止,即叶子结点,我们需要实现这样的建树。
这里的建树,我们可以用完全二叉树来比拟,对于一个完全二叉树,我们已知它的性质:
①某个父结点标号为k,则其左孩子的标号为2k,右孩子的标号就为2k+1,因此我们可以轻松推出。
②一个完全二叉树的高度为[log(n+1)](底数为2),其中n指结点的个数。
对于一个以[1,n]为根结点的线段树,其高度可能是[log(n+1)](底数为2)(比如n=1时),可能是[log(n+1)+1](底数为2)(比如n=2)。那么由高度反向推出结点个数最大为2^(log(n+1)+1)<2^(logn+2)(数学的放缩),因此高度h<2^(logn+2)=4*2^logn=4n,可以知道对于最大为n的数组,其结点的个数一定不超过4n,这样就明确了树状数组要开的大小了。
明确了这一点,需要的就是建树和执行题目描述的两个操作了,肯定都需要利用递归的操作的,并且都使用二分,这题就不会超时。
假设n为5,那么其根结点为[1,5],左右孩子为[1,3],[4,5]。[1,3]的左右孩子分别为[1,2],[3,3],然后[1,2]再细分。假如对下标为3的元素加上y,那么在线段树内[3,3],[1,3],[1,5]都需要加上y,因为都包含了下标3。

线段树代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5;
int n,m,a[maxn+1],f[4*maxn+1];//a数组用来存数,f数组用来计算处理后的值
void buildtree(int k,int l,int r){if(l==r){f[k]=a[l];return;}//叶子结点,一个线段就是一个点int mid=(l+r)>>1;//二分,也可以用/2,但是>>1的效率更高buildtree(k+k,l,mid);//左孩子buildtree(k+k+1,mid+1,r);//右孩子f[k]=f[k+k]+f[k+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(k+k,l,mid,x,y);//下标在左子树上else add(k+k+1,mid+1,r,x,y);//下标在右子树上
}
int calc(int k,int l,int r,int s,int t){//在区间l,r中找到s,t区间,得到线段值if(l==s&&r==t)return f[k];//找到了int mid=(l+r)>>1;if(t<=mid)//明显要找的区间在l,r区间的左子树上return calc(k+k,l,mid,s,t);elseif(s>mid)//要找的区间在l,r区间的右子树上return calc(k+k+1,mid+1,r,s,t);else//既有部分在左子树又有部分在右子树return calc(k+k,l,mid,s,mid)+calc(k+k+1,mid+1,r,mid+1,t);
}
int main(){cin>>n>>m;for(int i=1;i<=n;++i)scanf("%d",&a[i]);buildtree(1,1,n);//从编号为1的根结点开始while(m--){int t,x,y;scanf("%d%d%d",&t,&x,&y);if(t==1)add(1,1,n,x,y);//从编号1开始else printf("%d\n",calc(1,1,n,x,y));}
}

树状数组解法:
树状数组是简便快捷的方法,效率也高,但是底层的结构是有关于二进制的后缀和思想,比较难理解,强推这位大佬的文章:
树状数组简单易懂的详解

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
int n,m,a[500005],f[500005];
void update(int x,int value){for(;x<=n;x+=lowbit(x))f[x]+=value;
}
int sum(int x){int ans=0;for(;x>=0;x-=lowbit(x))ans+=f[x];return ans;
}
int main(){cin>>n>>m;for(int i=1;i<=n;++i)scanf("%d",&a[i]),update(i,a[i]);while(m--){int t,x,y;scanf("%d%d%d",&t,&x,&y);if(t==1)update(x,y);else printf("%d\n",sum(y)-sum(x-1));}
}

洛谷3374:树状数组1(线段树/树状数组模板)相关推荐

  1. 树状数组入门——以洛谷3374为例

    树状数组入门 含义:顾名思义,用树状表示的数组 功能:是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修改可以在log( ...

  2. 信息学奥赛一本通 1107:校门外的树 | 1931:【05NOIP普及组】校门外的树 | OpenJudge NOI 1.6 06 | 洛谷 P1047 [NOIP2005 普及组] 校门外的树

    [题目链接] ybt 1107:校门外的树 ybt 1931:[05NOIP普及组]校门外的树 OpenJudge NOI 1.6 06:校门外的树 洛谷 P1047 [NOIP2005 普及组] 校 ...

  3. 洛谷 深基 第1部分 语言入门 第5章 数组与数据批量存储

    P1428 小鱼比可爱 小鱼比可爱 - 洛谷 P1427 小鱼的数字游戏 小鱼的数字游戏 - 洛谷 P5727 [深基5.例3]冰雹猜想 [深基5.例3]冰雹猜想 - 洛谷 P5727 [深基5.例3 ...

  4. 洛谷 P1873 [COCI 2011/2012 #5] EKO / 砍树

    题目传送门: 洛谷 P1873 [COCI 2011/2012 #5] EKO / 砍树 题目描述 伐木工人 Mirko 需要砍 M 米长的木材.对 Mirko 来说这是很简单的工作,因为他有一个漂亮 ...

  5. 洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树(二分法)

    题目链接 : 洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树 文章目录 前言 一.题目 题目描述 输入格式 输出格式 输入输出样例 说明/提示 二.代码 前言 第一次写博客, ...

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

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

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

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

  8. 洛谷 2921 记忆化搜索 tarjan 基环外向树

    洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...

  9. [洛谷]P3353 在你窗外闪耀的星星 (#树状数组)

    题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀着你玫瑰色的 ...

  10. 洛谷P3960 列队(动态开节点线段树)

    题意 题目链接 Sol 看不懂splay..,看不懂树状数组... 只会暴力动态开节点线段树 观察之后不难发现,我们对于行和列需要支持的操作都是相同的:找到第\(k\)大的元素并删除,在末尾插入一个元 ...

最新文章

  1. maven项目转成web项目
  2. Matlab实用程序--图形应用-图形的隐藏属性
  3. 你做过的项目会逐渐形成你自己的认知和别人对于你的看法~剑桥工程硕士陶瓷有感
  4. centos 安装 acrobat Reader之后
  5. CF388D-Fox and Perfect Sets【dp,线性基】
  6. cxf开发基于web的webservice项目(转载)
  7. linux抓包库libpcap,linux下libpcap抓包分析.doc
  8. spring事务分类简述
  9. linux命令df命令全称,df命令--Linux命令应用大词典729个命令解读
  10. 嵌入式操作系统-ucos是什么?
  11. 好用且种类多的Unity3d游戏特效素材推荐,都在这里
  12. 【H5调用iOS原生高德定位】
  13. Termux设置自启动
  14. LibreOffice 宏
  15. 懒虫读诗 (树形dp+分组背包)
  16. 2021年的诀尘子和Vue
  17. 微信小程序开发者工具error:用户绑定的手机需要进行验证,请在客户端完成短信验证
  18. SAP常见问题与解决办法(转)
  19. 最长公共子序列问题-----题目
  20. Team Project Proposal: 开始页--为你的Outlook而生--By Qiaolin Xia

热门文章

  1. 3.Web中使用iReport 整合----------创建PDF格式的
  2. MySQL的备份与还原
  3. SQL 复合查询条件(AND,OR,NOT)对NULL值的处理
  4. ext数据库读取动态添加window组件
  5. windows server 2008 各版本下载
  6. ibmt41 安装linux系统,哥我决意为IBM T41 装WIN7的决心已经到了全人类都无法阻止的地步!...
  7. Unity3D Timeline 工作流
  8. 黑色的php编辑器,五款常用的免费php编辑器推荐
  9. python怎么在gui中显示图片_Python 3-如何从Web检索图像并使用TKINTER在GUI中显示?...
  10. HTTP与HTTPS之间的联系与连接状态