golang 解法, 执行用时: 520 ms, 内存消耗: 23.7 MB, 提交时间: 2023-11-13 00:18:10
type NumArray struct {
nums, sums []int // sums[i] 表示第 i 个块的元素和
size int // 块的大小
}
func Constructor(nums []int) NumArray {
n := len(nums)
size := int(math.Sqrt(float64(n)))
sums := make([]int, (n+size-1)/size) // n/size 向上取整
for i, num := range nums {
sums[i/size] += num
}
return NumArray{nums, sums, size}
}
func (na *NumArray) Update(index, val int) {
na.sums[index/na.size] += val - na.nums[index]
na.nums[index] = val
}
func (na *NumArray) SumRange(left, right int) (ans int) {
size := na.size
b1, b2 := left/size, right/size
if b1 == b2 { // 区间 [left, right] 在同一块中
for i := left; i <= right; i++ {
ans += na.nums[i]
}
return
}
for i := left; i < (b1+1)*size; i++ {
ans += na.nums[i]
}
for i := b1 + 1; i < b2; i++ {
ans += na.sums[i]
}
for i := b2 * size; i <= right; i++ {
ans += na.nums[i]
}
return
}
/**
* Your NumArray object will be instantiated and called as such:
* obj := Constructor(nums);
* obj.Update(index,val);
* param_2 := obj.SumRange(left,right);
*/
golang 解法, 执行用时: 504 ms, 内存消耗: 24.7 MB, 提交时间: 2023-11-13 00:17:55
type NumArray []int
func Constructor(nums []int) NumArray {
n := len(nums)
seg := make(NumArray, n*4)
seg.build(nums, 0, 0, n-1)
return seg
}
func (seg NumArray) build(nums []int, node, s, e int) {
if s == e {
seg[node] = nums[s]
return
}
m := s + (e-s)/2
seg.build(nums, node*2+1, s, m)
seg.build(nums, node*2+2, m+1, e)
seg[node] = seg[node*2+1] + seg[node*2+2]
}
func (seg NumArray) change(index, val, node, s, e int) {
if s == e {
seg[node] = val
return
}
m := s + (e-s)/2
if index <= m {
seg.change(index, val, node*2+1, s, m)
} else {
seg.change(index, val, node*2+2, m+1, e)
}
seg[node] = seg[node*2+1] + seg[node*2+2]
}
func (seg NumArray) range_(left, right, node, s, e int) int {
if left == s && right == e {
return seg[node]
}
m := s + (e-s)/2
if right <= m {
return seg.range_(left, right, node*2+1, s, m)
}
if left > m {
return seg.range_(left, right, node*2+2, m+1, e)
}
return seg.range_(left, m, node*2+1, s, m) + seg.range_(m+1, right, node*2+2, m+1, e)
}
func (seg NumArray) Update(index, val int) {
seg.change(index, val, 0, 0, len(seg)/4-1)
}
func (seg NumArray) SumRange(left, right int) int {
return seg.range_(left, right, 0, 0, len(seg)/4-1)
}
/**
* Your NumArray object will be instantiated and called as such:
* obj := Constructor(nums);
* obj.Update(index,val);
* param_2 := obj.SumRange(left,right);
*/
golang 解法, 执行用时: 472 ms, 内存消耗: 24.3 MB, 提交时间: 2023-11-13 00:17:39
type NumArray struct {
nums, tree []int
}
func Constructor(nums []int) NumArray {
tree := make([]int, len(nums)+1)
na := NumArray{nums, tree}
for i, num := range nums {
na.add(i+1, num)
}
return na
}
func (na *NumArray) add(index, val int) {
for ; index < len(na.tree); index += index & -index {
na.tree[index] += val
}
}
func (na *NumArray) prefixSum(index int) (sum int) {
for ; index > 0; index &= index - 1 {
sum += na.tree[index]
}
return
}
func (na *NumArray) Update(index, val int) {
na.add(index+1, val-na.nums[index])
na.nums[index] = val
}
func (na *NumArray) SumRange(left, right int) int {
return na.prefixSum(right+1) - na.prefixSum(left)
}
/**
* Your NumArray object will be instantiated and called as such:
* obj := Constructor(nums);
* obj.Update(index,val);
* param_2 := obj.SumRange(left,right);
*/
java 解法, 执行用时: 103 ms, 内存消耗: 69.6 MB, 提交时间: 2023-11-13 00:17:18
class NumArray {
private int[] sum; // sum[i] 表示第 i 个块的元素和
private int size; // 块的大小
private int[] nums;
public NumArray(int[] nums) {
this.nums = nums;
int n = nums.length;
size = (int) Math.sqrt(n);
sum = new int[(n + size - 1) / size]; // n/size 向上取整
for (int i = 0; i < n; i++) {
sum[i / size] += nums[i];
}
}
public void update(int index, int val) {
sum[index / size] += val - nums[index];
nums[index] = val;
}
public int sumRange(int left, int right) {
int b1 = left / size, i1 = left % size, b2 = right / size, i2 = right % size;
if (b1 == b2) { // 区间 [left, right] 在同一块中
int sum = 0;
for (int j = i1; j <= i2; j++) {
sum += nums[b1 * size + j];
}
return sum;
}
int sum1 = 0;
for (int j = i1; j < size; j++) {
sum1 += nums[b1 * size + j];
}
int sum2 = 0;
for (int j = 0; j <= i2; j++) {
sum2 += nums[b2 * size + j];
}
int sum3 = 0;
for (int j = b1 + 1; j < b2; j++) {
sum3 += sum[j];
}
return sum1 + sum2 + sum3;
}
}
class NumArray2 {
private int[] segmentTree;
private int n;
public NumArray2(int[] nums) {
n = nums.length;
segmentTree = new int[nums.length * 4];
build(0, 0, n - 1, nums);
}
public void update(int index, int val) {
change(index, val, 0, 0, n - 1);
}
public int sumRange(int left, int right) {
return range(left, right, 0, 0, n - 1);
}
private void build(int node, int s, int e, int[] nums) {
if (s == e) {
segmentTree[node] = nums[s];
return;
}
int m = s + (e - s) / 2;
build(node * 2 + 1, s, m, nums);
build(node * 2 + 2, m + 1, e, nums);
segmentTree[node] = segmentTree[node * 2 + 1] + segmentTree[node * 2 + 2];
}
private void change(int index, int val, int node, int s, int e) {
if (s == e) {
segmentTree[node] = val;
return;
}
int m = s + (e - s) / 2;
if (index <= m) {
change(index, val, node * 2 + 1, s, m);
} else {
change(index, val, node * 2 + 2, m + 1, e);
}
segmentTree[node] = segmentTree[node * 2 + 1] + segmentTree[node * 2 + 2];
}
private int range(int left, int right, int node, int s, int e) {
if (left == s && right == e) {
return segmentTree[node];
}
int m = s + (e - s) / 2;
if (right <= m) {
return range(left, right, node * 2 + 1, s, m);
} else if (left > m) {
return range(left, right, node * 2 + 2, m + 1, e);
} else {
return range(left, m, node * 2 + 1, s, m) + range(m + 1, right, node * 2 + 2, m + 1, e);
}
}
}
class NumArray3 {
private int[] tree;
private int[] nums;
public NumArray3(int[] nums) {
this.tree = new int[nums.length + 1];
this.nums = nums;
for (int i = 0; i < nums.length; i++) {
add(i + 1, nums[i]);
}
}
public void update(int index, int val) {
add(index + 1, val - nums[index]);
nums[index] = val;
}
public int sumRange(int left, int right) {
return prefixSum(right + 1) - prefixSum(left);
}
private int lowBit(int x) {
return x & -x;
}
private void add(int index, int val) {
while (index < tree.length) {
tree[index] += val;
index += lowBit(index);
}
}
private int prefixSum(int index) {
int sum = 0;
while (index > 0) {
sum += tree[index];
index -= lowBit(index);
}
return sum;
}
}
/**
* 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);
*/
cpp 解法, 执行用时: 452 ms, 内存消耗: 168.3 MB, 提交时间: 2023-11-13 00:16:10
class NumArray1 {
private:
vector<int> sum; // sum[i] 表示第 i 个块的元素和
int size; // 块的大小
vector<int> &nums;
public:
NumArray1(vector<int>& nums) : nums(nums) {
int n = nums.size();
size = sqrt(n);
sum.resize((n + size - 1) / size); // n/size 向上取整
for (int i = 0; i < n; i++) {
sum[i / size] += nums[i];
}
}
void update(int index, int val) {
sum[index / size] += val - nums[index];
nums[index] = val;
}
int sumRange(int left, int right) {
int b1 = left / size, i1 = left % size, b2 = right / size, i2 = right % size;
if (b1 == b2) { // 区间 [left, right] 在同一块中
return accumulate(nums.begin() + b1 * size + i1, nums.begin() + b1 * size + i2 + 1, 0);
}
int sum1 = accumulate(nums.begin() + b1 * size + i1, nums.begin() + b1 * size + size, 0);
int sum2 = accumulate(nums.begin() + b2 * size, nums.begin() + b2 * size + i2 + 1, 0);
int sum3 = accumulate(sum.begin() + b1 + 1, sum.begin() + b2, 0);
return sum1 + sum2 + sum3;
}
};
class NumArray2 {
private:
vector<int> segmentTree;
int n;
void build(int node, int s, int e, vector<int> &nums) {
if (s == e) {
segmentTree[node] = nums[s];
return;
}
int m = s + (e - s) / 2;
build(node * 2 + 1, s, m, nums);
build(node * 2 + 2, m + 1, e, nums);
segmentTree[node] = segmentTree[node * 2 + 1] + segmentTree[node * 2 + 2];
}
void change(int index, int val, int node, int s, int e) {
if (s == e) {
segmentTree[node] = val;
return;
}
int m = s + (e - s) / 2;
if (index <= m) {
change(index, val, node * 2 + 1, s, m);
} else {
change(index, val, node * 2 + 2, m + 1, e);
}
segmentTree[node] = segmentTree[node * 2 + 1] + segmentTree[node * 2 + 2];
}
int range(int left, int right, int node, int s, int e) {
if (left == s && right == e) {
return segmentTree[node];
}
int m = s + (e - s) / 2;
if (right <= m) {
return range(left, right, node * 2 + 1, s, m);
} else if (left > m) {
return range(left, right, node * 2 + 2, m + 1, e);
} else {
return range(left, m, node * 2 + 1, s, m) + range(m + 1, right, node * 2 + 2, m + 1, e);
}
}
public:
NumArray2(vector<int>& nums) : n(nums.size()), segmentTree(nums.size() * 4) {
build(0, 0, n - 1, nums);
}
void update(int index, int val) {
change(index, val, 0, 0, n - 1);
}
int sumRange(int left, int right) {
return range(left, right, 0, 0, n - 1);
}
};
class NumArray {
private:
vector<int> tree;
vector<int> &nums;
int lowBit(int x) {
return x & -x;
}
void add(int index, int val) {
while (index < tree.size()) {
tree[index] += val;
index += lowBit(index);
}
}
int prefixSum(int index) {
int sum = 0;
while (index > 0) {
sum += tree[index];
index -= lowBit(index);
}
return sum;
}
public:
NumArray(vector<int>& nums) : tree(nums.size() + 1), nums(nums) {
for (int i = 0; i < nums.size(); i++) {
add(i + 1, nums[i]);
}
}
void update(int index, int val) {
add(index + 1, val - nums[index]);
nums[index] = val;
}
int sumRange(int left, int right) {
return prefixSum(right + 1) - prefixSum(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);
*/
python3 解法, 执行用时: 1088 ms, 内存消耗: 34.3 MB, 提交时间: 2023-11-13 00:14:24
# 分块处理
class NumArray1:
def __init__(self, nums: List[int]):
n = len(nums)
size = int(n ** 0.5)
sums = [0] * ((n + size - 1) // size) # n/size 向上取整
for i, num in enumerate(nums):
sums[i // size] += num
self.nums = nums
self.sums = sums
self.size = size
def update(self, index: int, val: int) -> None:
self.sums[index // self.size] += val - self.nums[index]
self.nums[index] = val
def sumRange(self, left: int, right: int) -> int:
m = self.size
b1, b2 = left // m, right // m
if b1 == b2: # 区间 [left, right] 在同一块中
return sum(self.nums[left:right + 1])
return sum(self.nums[left:(b1 + 1) * m]) + sum(self.sums[b1 + 1:b2]) + sum(self.nums[b2 * m:right + 1])
# 线段树
class NumArray2:
def __init__(self, nums: List[int]):
n = len(nums)
self.n = n
self.seg = [0] * (n * 4)
self.build(nums, 0, 0, n - 1)
def build(self, nums: List[int], node: int, s: int, e: int):
if s == e:
self.seg[node] = nums[s]
return
m = s + (e - s) // 2
self.build(nums, node * 2 + 1, s, m)
self.build(nums, node * 2 + 2, m + 1, e)
self.seg[node] = self.seg[node * 2 + 1] + self.seg[node * 2 + 2]
def change(self, index: int, val: int, node: int, s: int, e: int):
if s == e:
self.seg[node] = val
return
m = s + (e - s) // 2
if index <= m:
self.change(index, val, node * 2 + 1, s, m)
else:
self.change(index, val, node * 2 + 2, m + 1, e)
self.seg[node] = self.seg[node * 2 + 1] + self.seg[node * 2 + 2]
def range(self, left: int, right: int, node: int, s: int, e: int) -> int:
if left == s and right == e:
return self.seg[node]
m = s + (e - s) // 2
if right <= m:
return self.range(left, right, node * 2 + 1, s, m)
if left > m:
return self.range(left, right, node * 2 + 2, m + 1, e)
return self.range(left, m, node * 2 + 1, s, m) + self.range(m + 1, right, node * 2 + 2, m + 1, e)
def update(self, index: int, val: int) -> None:
self.change(index, val, 0, 0, self.n - 1)
def sumRange(self, left: int, right: int) -> int:
return self.range(left, right, 0, 0, self.n - 1)
# 树状数组
class NumArray:
def __init__(self, nums: List[int]):
self.nums = nums
self.tree = [0] * (len(nums) + 1)
for i, num in enumerate(nums, 1):
self.add(i, num)
def add(self, index: int, val: int):
while index < len(self.tree):
self.tree[index] += val
index += index & -index
def prefixSum(self, index) -> int:
s = 0
while index:
s += self.tree[index]
index &= index - 1
return s
def update(self, index: int, val: int) -> None:
self.add(index + 1, val - self.nums[index])
self.nums[index] = val
def sumRange(self, left: int, right: int) -> int:
return self.prefixSum(right + 1) - self.prefixSum(left)
# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# obj.update(index,val)
# param_2 = obj.sumRange(left,right)
python3 解法, 执行用时: 684 ms, 内存消耗: N/A, 提交时间: 2018-08-31 15:01:44
class NumArray:
def __init__(self, nums):
"""
:type nums: List[int]
"""
self.nums = nums
def update(self, i, val):
"""
:type i: int
:type val: int
:rtype: void
"""
self.nums[i] = val
def sumRange(self, i, j):
"""
:type i: int
:type j: int
:rtype: int
"""
return sum(self.nums[i:j+1])
# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# obj.update(i,val)
# param_2 = obj.sumRange(i,j)