【YbtOJ 树状数组 - 1】单点修改区间查询

博客介绍了如何使用树状数组解决单点修改和区间查询的问题。通过给出的输入输出样例,详细解析了解题思路,并提供了相应的程序实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单点修改区间查询


题目

在这里插入图片描述


输入

在这里插入图片描述

输出

对于每个 222 lll rrr 操作输出一行,每行有一个整数,表示所求的结果


输入样例

3 2
1 2 3
1 2 0
2 1 3

输出样例

6

解题思路

这题用的是树状数组,树状数组支持单点加操作,还支持查询前缀和,这题我们就直接可以用到


程序如下

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;

int n, m, r;

long long c[1000001];

void update(int x, int y)//加法操作
{
	for(; x <= n; x += x & -x) c[x] += y;
}

long long query(long long x)//查询操作
{
	long long ans = 0;
	for(; x; x -= x & -x) ans += c[x];
	return ans;
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; ++i)
	{
		int val;
		scanf("%d",&val);
		update(i, val);
	}
	for(int i = 1; i <= m; ++i)
	{
		scanf("%d",&r);
		if(r == 1)
		{
			int x, k;
			scanf("%d%d",&x,&k);
			update(x, k);
		}
		else if(r == 2)
		{
			int x, y;
			scanf("%d%d",&x,&y);
			printf("%lld\n",query(y) - query(x - 1));
		}
	}
	return 0;
} 
### 使用二维树状数组实现单点更新和区域求和 #### 一维树状数组简介 在一维情况下,树状数组(Fenwick Tree)能够高效地完成单点修改和前缀和查询的操作。对于任意位置 `i` 的元素增加某个值 `delta` 或者计算从起点到当前位置的累积和,时间复杂度均为 O(log n)[^2]。 #### 构建二维树状数组 为了处理更复杂的场景——即在一个 n×n 大小的矩形区域内执行类似的增减操作并快速获取指定子矩阵内的总和,在此基础上扩展出了二维版本的树状数组。其核心思想是在每一行都维护一棵独立的一维树状数组来记录该行各列上的累计变化情况;当涉及到跨多行或多列范围时,则通过遍历这些受影响的部分来进行累加得到最终的结果[^1]。 #### 更新函数 针对特定坐标 `(x,y)` 进行数值调整时,不仅需要改变当前节点所对应的那一棵内部树状数组中的相应项,还要沿着 x 和 y 方向分别向上寻找所有可能影响到其他部分的位置,并依次对其作出相同幅度的变化: ```cpp void update(int x, int y, int delta){ while(x <= N){ // 对于每一个受此更改影响的新行号... int ty=y; while(ty<=N){ tree[x][ty]+=delta; // ...及其内每列上对应位置处存储的信息也要同步变动. ty+=lowbit(ty); } x += lowbit(x); } } ``` 这里定义了一个辅助性的 `lowbit()` 函数用于提取整型变量最右边那个'1'代表的具体权值大小,这有助于确定下一步应该访问哪个相邻结点继续传播增量信息。 #### 查询函数 要获得由左下角位于`(a,b)`而右上角处于`(c,d)`之间的矩形单元格组成的连续片段里全部元素之和,可以先算出整个大正方形覆盖范围内所有数据相加之总量,再从中扣除掉超出目标边界以外多余部分各自的贡献即可得出正确答案: ```cpp int query(int a,int b,int c,int d){ return getsum(c,d)-getsum(a-1,d)-getsum(c,b-1)+getsum(a-1,b-1); } // 辅助函数:返回原点至某一点之间所有数目的合计。 int getsum(int x, int y){ int sum=0; while(y>0){ int tx=x; while(tx>0){ sum+=tree[tx][y]; tx-=lowbit(tx); } y -= lowbit(y); } return sum; } ``` 上述代码实现了基于二维树状数组结构下的单点更新与区间求和功能,其中涉及到了两次嵌套循环迭代过程以确保能全面考虑到各个维度方向上传播的影响因素[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值