307.区域和检索 - 数组可修改

题目

307.区域和检索 - 数组可修改

题目大意

给你一个数组 nums ,请你完成两类查询。

  1. 其中一类查询要求 更新 数组 nums 下标对应的值
  2. 另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 ,其中 left <= right

实现 NumArray 类:

  • NumArray(int[] nums) 用整数数组 nums 初始化对象
  • void update(int index, int val)nums[index] 的值 更新val
  • int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 (即,nums[left] + nums[left + 1], ..., nums[right]

样例

示例 1:

输入:
["NumArray", "sumRange", "update", "sumRange"]
[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]
输出:
[null, 9, null, 8]

解释:
NumArray numArray = new NumArray([1, 3, 5]);
numArray.sumRange(0, 2); // 返回 1 + 3 + 5 = 9
numArray.update(1, 2);   // nums = [1,2,5]
numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8

数据规模

提示:

  • 1 < = n u m s . l e n g t h < = 3 ∗ 1 0 4 1 <= nums.length <= 3 * 10^4 1<=nums.length<=3104
  • -100 <= nums[i] <= 100
  • 0 <= index < nums.length
  • -100 <= val <= 100
  • 0 <= left <= right < nums.length
  • 调用 updatesumRange 方法次数不大于 3 ∗ 1 0 4 3 * 10^4 3104

思路

单点修改统计区间和问题:直接套用树状数组模板即可。

vector<int>sum用于统计区间和;函数add用于将x下标之后的区间全部加 k k k;函数query统计区间 [ 1 , x ] [1,x] [1,x]的总和。首先将数组nums的元素全部加入到树状数组中,然后对于update操作先将 i n d e x + 1 index+1 index+1(默认从 1 1 1开始)之后的区间全部加 v a l − a [ i n d e x ] val-a[index] vala[index],对于sumRange函数统计区间和: q u e r y ( r i g h t + 1 ) − q u e r y ( l e f t ) query(right+1)-query(left) query(right+1)query(left)

代码

// short int long float double bool char string void
// array vector stack queue auto const operator
// class public private static friend extern 
// sizeof new delete return cout cin memset malloc
// relloc size length memset malloc relloc size length
// for while if else switch case continue break system
// endl reverse sort swap substr begin end iterator
// namespace include define NULL nullptr exit equals 
// index col row arr err left right ans res vec que sta
// state flag ch str max min default charray std
// maxn minn INT_MAX INT_MIN push_back insert
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int>PII;
typedef pair<int, string>PIS;
const int maxn=3e4+50;//注意修改大小
long long read(){long long x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;}
ll qpow(ll x,ll q,ll Mod){ll ans=1;while(q){if(q&1)ans=ans*x%Mod;q>>=1;x=(x*x)%Mod;}return ans%Mod;}

class NumArray {
public:
	vector<int>a;
	int n;
	vector<int>sum;
	int lowbit(int x)
	{
		return x&(-x);	
	} 
	void add(int x,int k)
	{
		while(x<=n)
		{
			sum[x]+=k;
			x+=lowbit(x);
		}
	}
	int query(int x)
	{
		int res=0;
		while(x)
		{
			res+=sum[x];
			x-=lowbit(x);
		}
		return res;
	}
    NumArray(vector<int>& nums):a(nums),sum(nums.size()+1) {
		n=a.size();
		for(int i=1;i<=n;i++)add(i,a[i-1]);
    }
    
    void update(int index, int val) {
		add(index+1,val-a[index]);
		a[index]=val;
    }
    
    int sumRange(int left, int right) {
		return query(right+1)-query(left);
    }
};

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray* obj = new NumArray(nums);
 * obj->update(index,val);
 * int param_2 = obj->sumRange(left,right);
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Phoenix_ZengHao

创作不易,能否打赏一瓶饮料?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值