P3374 树状数组 1

题目描述

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

1.将某一个数加上x

2.求出某区间每一个数的和

输入输出格式

输入格式:
第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

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

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

操作1: 格式:1 x k 含义:将第x个数加上k

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

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

输入输出样例

输入样例#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
说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=10000,M<=10000

对于100%的数据:N<=500000,M<=500000

样例说明:

故输出结果14、16

题解:
题目很很清楚,用树状数组解决。

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,k,x,y,t,ans;
int a[500000],c[500000];
int lowbit(int x)
{
    return x&(-x);
}
int sum(int x)
{
    ans=0;
    for(int i=x;i>0;i=i-lowbit(i))
        ans=ans+c[i];
    return ans;
}
void update(int x,int d)
{
    for(int i=x;i<=n;i=i+lowbit(i))
        c[i]=c[i]+d;
    return;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        update(i,a[i]);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&k,&x,&y);
        if(k==1)
            update(x,y);
        if(k==2)
            printf("%d\n",sum(y)-sum(x-1));
    }
    return 0;
}
### 关于树状数组(Binary Indexed Tree) #### 定义 所谓树状数组,并不是真正意义上的树形结构,而是通过数组形式模拟的一种特殊的数据结构。这种数据结构利用数字的二进制表示方法对元素进行逻辑上的分层存储[^1]。 #### 特点 树状数组是一种能够高效处理前缀和查询以及单点更新问题的数据结构,其查询和修改的时间复杂度均为 \(O(\log n)\)[^2]。这使得树状数组非常适合用于解决涉及频繁区间求和及元素更改的问题场景。 #### 设计思想 设计上采用了巧妙的方式——基于二进制索引规则与位运算相结合的方法,在保持较低空间开销的同时实现了高效的动态数组更新和查询功能[^3]。 #### Java 实现示例 下面给出一个简单的Java版本的树状数组实现: ```java public class BinaryIndexedTree1D { private final int[] bit; public BinaryIndexedTree1D(int size) { this.bit = new int[size + 1]; } /** * 更新指定位置处的值。 * * @param index 需要更新的位置(从1开始编号) * @param delta 变化量 */ public void update(int index, int delta) { while (index < bit.length) { bit[index] += delta; index += index & (-index); } } /** * 查询给定位置之前的累积和。 * * @param index 要查询的位置(从1开始编号) * @return 返回该位置之前所有数之和 */ public int query(int index) { int sum = 0; while (index > 0) { sum += bit[index]; index -= index & (-index); } return sum; } } ``` 此代码片段展示了如何创建一个一维的树状数组类 `BinaryIndexedTree1D` ,并提供了两个核心函数:一个是用来增加某个特定下标的数值(`update`);另一个是用来计算到某一下标为止的所有数值总和(`query`)[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值