难点-树状数组

树状数组 1 :单点修改,区间查询

题目描述

这是一道模板题。

给定数列 a1​,a2​,…,an​,你需要依次进行 q 个操作,操作有两类:

  • 1 i x:给定 i,x,将 ai​ 加上 x;
  • 2 l r:给定 l,r,求∑i=lr​ai​ 的值(换言之,求al​+al+1​+⋯+ar​ 的值)。

输入格式

第一行包含 2 个正整数 n,q,表示数列长度和询问个数。保证1≤n,q≤1e6。
第二行 n 个整数 a1​,a2​,…,an​,表示初始数列。保证 ∣ai​∣≤1e6。
接下来 q 行,每行一个操作,为以下两种之一:

  • 1 i x:给定 i,x,将 a[i] 加上 x;
  • 2 l r:给定 l,r,求 ∑i=lr​ai​ 的值。

保证 1≤l≤r≤n, ∣x∣≤1e6。

输出格式

对于每个 2 l r 操作输出一行,每行有一个整数,表示所求的结果。

样例

InputOutput
3 2
1 2 3
1 2 0
2 1 3
6

AC代码:

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <list>
#include <set>
#include <istream>
#include <sstream>
#include <iomanip>
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
using namespace std;
int n,q;
int a[1000010];
long long tree[1000010];
int lowbit(int x){
	return x & -x;
}
void add(int x,int v){
	while(x <= n){
		tree[x] += v;
		x += lowbit(x);
	}
}
long long get(int x){
	long long cnt = 0;
	while(x){
		cnt += tree[x];
		x -= lowbit(x);
	}
	return cnt;
}
void solve(){
	cin >> n >> q;
	for(int i = 1;i <= n;i++){
		cin >> a[i];
		add(i,a[i]);
	}
	while(q--){
		int id,x,y;
		cin >> id >> x >> y;
		if(id == 1){
			add(x,y);
		}
		if(id == 2){
			cout << get(y) - get(x - 1) << endl;
		}
	}
	return ;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	solve();
	return 0;
}
/*

*/

树状数组 2 :区间修改,单点查询:

题目描述

这是一道模板题。

给定数列 a[1],a[2],…,a[n],你需要依次进行 q 个操作,操作有两类:

  • 1 l r x:给定 l,r,x,对于所有i∈[l,r],将 a[i] 加上 x(换言之,将 a[l],a[l+1],…,a[r] 分别加上 x);
  • 2 i:给定 i,求 a[i] 的值。

输入格式

第一行包含 2 个正整数 n,q,表示数列长度和询问个数。保证 1≤n,q≤1e6。
第二行 n 个整数a[1],a[2],…,a[n],表示初始数列。保证a[i]∣≤1e6。
接下来 q 行,每行一个操作,为以下两种之一:

  • 1 l r x:对于所有i∈[l,r],将 a[i] 加上 x;
  • 2 i:给定 i,求 a[i] 的值。

保证1≤l≤r≤n,∣x∣≤1e6。

输出格式

对于每个 2 i 操作,输出一行,每行有一个整数,表示所求的结果。

样例

InputOutput
3 2
1 2 3
1 1 3 0
2 2
2

AC代码:

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <list>
#include <set>
#include <istream>
#include <sstream>
#include <iomanip>
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
using namespace std;
int n,q;
int a[1000010],b[1000010];
long long tree[1000010];
int lowbit(int x){
	return x & -x;
}
void add(int x,int v){
	while(x <= n){
		tree[x] += v;
		x += lowbit(x);
	}
}
long long get(int x){
	long long cnt = 0;
	while(x){
		cnt += tree[x];
		x -= lowbit(x);
	}
	return cnt;
}
void solve(){
	cin >> n >> q;
	for(int i = 1;i <= n;i++){
		cin >> a[i];
		if(i == 1){
			b[1] = a[1];
		}
		else{
			b[i] = a[i] - a[i - 1];
		}
	}
	for(int i = 1;i <= n;i++){
		tree[i] += b[i];
		long long j = i + lowbit(i);
		if(j <= n){
			tree[j] += tree[i];
		}
	}
	while(q--){
		int id,l,r,x;
		cin >> id;
		if(id == 1){
			cin >> l >> r >> x;
			add(l,x);
			add(r + 1,-x);
		}
		if(id == 2){
			cin >> l;
			cout << get(l) << endl;
		}
	}
	return ;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	solve();
	return 0;
}
/*

*/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
扁平数组转换成树状数组(也称为二维数组或矩阵)多层表示的过程涉及将一维数据按照层次结构重新组织。通常,这种转换用于解决一些特定的问题,如矩阵操作、多维索引查询等。 假设我们有一个扁平的一维数组 `flatArray`,它的元素按列顺序排列,例如: ``` flatArray = [0, 1, 2, 3, 4, 5] ``` 如果我们想要将其转换为三层的树状数组,我们可以按照以下规则构建: 第 1 层是一个包含所有元素的第一级节点,即每一项都是单个节点。 第 2 层是对第 1 层的元素分组,每个子组包含一定数量的节点,这个数量取决于你想如何划分第二层。例如,如果每行有2个元素,那么第一层的两个元素会组合在一起形成第二个层级的单一节点,而第三个元素单独形成另一个二级节点。 第 3 层可以看作是第二层的进一步细化,对于每一组的内部结构,你可以继续应用上述规则。 这里是一个简单的示例,假设有三层: ```python # 第一层 layer_1 = [0, 1, 2, 3, 4, 5] # 第二层 # 我们将元素分为两列并创建节点对 layer_2 = [(layer_1, layer_1), (layer_1, layer_1), (layer_1, layer_1)] # 第三层 # 对于每一组,我们可以创建更多的内部结构。这取决于具体的需求。这里是简单的展开示例: layer_3 = [] for pair in layer_2: # 这里可以根据需要创建更细的结构。例如,每个pair可以代表一个“小块”,该“小块”由内部元素构成。这个例子中我们简单地保持每个pair作为一个独立的小块: layer_3.extend(pair) # 输出结果: print("Layer 1:", layer_1) print("Layer 2:", layer_2) print("Layer 3:", layer_3) ``` 运行上面的代码会得到输出类似于这样的结果: ``` Layer 1: [0, 1, 2, 3, 4, 5] Layer 2: [(0, 1), (2, 3), (4, 5)] Layer 3: [0, 1, 2, 3, 4, 5] ``` 请注意,这个示例相对简陋,并未深入处理第三层的实际数据结构。实际上,在第三层,你需要根据具体的业务需求来设计数据的存储和访问方式。 **相关问题**: 1. 在什么场景下需要将扁平数组转换为树状数组或多层表示? 2. 转换过程中需要注意哪些细节? 3. 树状数组转换后如何优化查找效率?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值