树状数组基础

关于树状数组的讲解推荐《算法竞赛入门经典训练指南》

一维版本:

洛谷3374

链接:https://www.luogu.org/problem/show?pid=3374

分析:树状数组裸的模板题

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=500000+10;
 6 int c[maxn];
 7 int n,m;
 8 int lowbit(int x){
 9     return x&(-x);
10 }
11 void add(int x,int d){
12     while(x<=n){
13         c[x]+=d; x+=lowbit(x);
14     }
15 }
16 int sum(int x){
17     int ret=0;
18     while(x>0){
19         ret+=c[x]; x-=lowbit(x);
20     }
21     return ret;
22 }
23 int main()
24 {
25     cin>>n>>m;
26     memset(c,0,sizeof(c));
27     for(int i=1;i<=n;i++){
28         int x;
29         scanf("%d",&x);
30         add(i,x);
31     }
32     while(m--){
33         int num,a,b;
34         scanf("%d%d%d",&num,&a,&b);
35         if(num==1){
36             add(a,b);
37         }else{
38             printf("%d\n",sum(b)-sum(a-1));
39         }
40     }
41     return 0;
42 }

二维版本:

vijos1512

链接:https://vijos.org/p/1512

分析:二维树状数组的裸题,注意面积的计算

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=2000;
 8 int c[maxn][maxn];
 9 int n,m;
10 int lowbit(int x){
11     return x&(-x);
12 }
13 void add(int x,int y,int d){
14     for(int i=x;i<=n;i+=lowbit(i))
15         for(int j=y;j<=n;j+=lowbit(j))
16             c[i][j]+=d;
17 }
18 int sum(int x,int y){
19     int ret=0;
20     for(int i=x;i>0;i-=lowbit(i))
21         for(int j=y;j>0;j-=lowbit(j))
22             ret+=c[i][j];
23     return ret;
24 }
25 int main()
26 {
27     scanf("%d",&n);
28     memset(c,0,sizeof(c));
29     while(scanf("%d",&m)!=EOF){
30         if(m==3) break;
31         if(m==1){
32             int x,y,k;
33             scanf("%d%d%d",&x,&y,&k);
34             add(x+1,y+1,k);
35         }else{
36             int x1,y1,x2,y2;
37             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
38             int cnt=sum(x2+1,y2+1)-sum(x1,y2+1)-sum(x2+1,y1)+sum(x1,y1);
39             printf("%d\n",cnt);
40         }
41     }
42     return 0;
43 }

时间: 2024-10-13 21:59:32

树状数组基础的相关文章

树状数组(二叉索引树 BIT Fenwick树) *【一维基础模板】(查询区间和+修改更新)

刘汝佳:<训练指南>Page(194) #include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; //一维树状数组基础模板 int lowbit(int x) { return x&(-x); } int c[1001]; int sum(int x) //计算从1到x的数组元素的和 { int

51nod_1199 树的先跟遍历+区间更新树状数组

题目是中文,所以不讲题意 做法顺序如下: 使用先跟遍历,把整棵树平铺到一维平面中 使用自己整的区间更新树状数组模板进行相关操作. http://www.cnblogs.com/rikka/p/7359185.html 放代码如下: 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 6 /* 7 *常量MAXN用于设定树状数组的尺寸大小 8 */ 9 const long long MAXN=500233; 10 class TreeL

POJ 2029 Get Many Persimmon Trees (二维树状数组 or DP)

题意:一个H * W的大矩形,里面的某些格子种有树.现在要你找出一个h * w的小矩形,使得里面树的数量最多,问最多有多少棵树 是二维树状数组基础用法,边输入边更新有树的点,建完树后就可以查询每个(1,1)到(x,y)为对顶点的矩形中共有多少棵柿子树. 算法复杂度 O(H*W*lgH*lgW) 但是由于这题的柿子树一旦确定位置后就没有更新位置,所以不需要用树状数组也可,直接用dp统计每个(1,1)到(x,y)为对顶点的矩形中共有多少棵柿子树. 统计的状态转移方程是: for(int i=1;i<

HDU1541 Stars(树状数组)

Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7209    Accepted Submission(s): 2830 Problem Description Astronomers often examine star maps where stars are represented by points on a pla

POJ 1195——Mobile phones(二维树状数组)

Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 15013   Accepted: 6957 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The

树状数组详解(图形学算法)

目录 一.从图形学算法说起 1.Median Filter 概述 2.r pixel-Median Filter 算法 3.一维模型 4.数据结构的设计 5.树状数组华丽登场 二.细说树状数组 1.树 or 数组? 2.结点的含义 3.求和操作 4.更新操作 5.lowbit函数O(1)实现 6.小结 三.树状数组的经典模型 1.PUIQ模型 2.IUPQ模型 3.逆序模型 4.二分模型 5.再说Median Filter 6.多维树状数组模型 四.树状数组题集整理 一.从图形学算法说起 1.M

2019.9.25 初级数据结构——树状数组

一.树状数组基础 学OI的同学都知道,位运算(对二进制的运算)比普通运算快很多.同时我们接触到了状态压缩的思想(即将0-1的很多个状态压缩成十进制的一个数,每一个二进制位表示一个状态).由于在实际做题过程当中,由于数据范围限制,我们必须采用更高效的存储.查询方法,于是树状数组应运而生. 首先我们检查传统的存储状态.对于数组的每一个下标i,其所存储的有效信息只有一个a[i](这是传统数组).而对于树状数组,我们每一位下标可以存储lowbit(i)个有效信息.这个lowbit运算一会再说.所以尽管树

算法基础-树状数组

今天我们分享一下树状数组,前置知识-了解树的结构,知道什么是左右儿子,各个节点的名称,也就是有点基础吧.今天以一个实际问题引出树状数组吧,中查询l-r的区间.(以B站大佬的课件为例子,可以关注下,在最后放上链接) 如果是暴力的话,显然时间复杂度是接受不了的(o(n方)),为了解决这个问题,我们就要用一些高级的数据结构.就是我们今天介绍的树状数组. 首先看下树状数组是什么, 树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log

树状数组的原理和基础应用

这样的数据结构称作树状数组,它支持O(logN)的单点修改和区间查询,效率高并且代码简洁,缺点在于适用范围不如线段树广.不难看出(雾),tree[i]表示a[i]及之前的 lowbit(i)个 数,定义lowbit(i)等于取i的二进制中最后一个'1'表示的大小观察发现(.),修改a[i]只需更新包含i的节点,倒推可知从i开始,每次把i加上lowbit(i),这些节点包含了a[i]从i开始,每次把i减去lowbit(i)直到为0,这些节点的值加起来就是前缀和.例题1:树状数组1  https:/