2025-01-04:不包含相邻元素的子序列的最大和。用go语言,给定一个整数数组 nums 和一个由二维数组 queries 组成的查询列表,其中每个查询的格式为 queries[i] = [posi, xi]。

对于每个查询 i,首先将 nums[posi] 的值更新为 xi,然后计算在这一更新后,数组 nums 中所有不包含相邻元素的子序列的最大和。

最后,返回所有查询的结果之和。需要注意的是,由于最终答案可能非常大,因此要对其进行 1000000007 的取余处理。

请根据以上描述进行相关的处理。

1 <= nums.length <= 5 * 10000。

-100000 <= nums[i] <= 100000。

1 <= queries.length <= 5 * 10000。

queries[i] == [posi, xi]。

0 <= posi <= nums.length - 1。

-100000 <= xi <= 100000。

答案2025-01-04:

chatgpt

题目来自leetcode3165。

大体步骤如下:

1.定义了一个常量 MOD 为 1000000007,表示取余处理的数值。

2.实现了一个函数 maximumSumSubsequence,该函数接受一个整数数组 nums 以及一个查询列表 queries。首先创建一个长度为 nums 数组长度四倍的线段树 tree,然后初始化这颗线段树根据传入的 nums 数组。接着对 queries 中的每个查询进行处理:更新 nums 中指定位置的值,并计算不包含相邻元素的子序列的最大和,并将结果取余加到 ans 中。最终返回 ans。

3.定义了一个结构体 SegNode,包含四个成员变量 v00、v01、v10、v11,表示线段树中的四种情况。

4.实现了两个 SegNode 结构体的方法:Set 和 Best,分别用于设置节点的值和获取最佳值。

5.定义了一个结构体 SegTree,包含了一个整数 n 和一个指向 SegNode 结构体数组的指针 tree。

6.实现了一个 NewSegTree 函数用于创建一个 SegTree 结构体并初始化相关信息。

7.实现了 SegTree 结构体的方法:Init、Update、Query、internalInit、internalUpdate、pushup。这些方法用于初始化线段树、更新节点值、查询最佳值等功能。

8.在 main 函数中,给定了一个示例数组 nums 和查询 queries,然后调用 maximumSumSubsequence 函数计算不包含相邻元素的子序列的最大和,并打印结果。

总的时间复杂度:

  • 初始化线段树的时间复杂度为 O(n)。

  • 每次查询的时间复杂度为 O(logn)。

  • 因此,总的时间复杂度为 O(n + q*logn),其中 n 为数组长度,q 为查询次数。

总的额外空间复杂度:

  • 线段树的空间复杂度为 O(n)。

  • 因此,总的额外空间复杂度为 O(n),其中 n 为数组长度。

Go完整代码如下:

package main

import (
"fmt"
"math"
) const MOD = 1000000007 func maximumSumSubsequence(nums []int, queries [][]int) int {
n := len(nums)
tree := NewSegTree(n)
tree.Init(nums) ans := int64(0)
for _, q := range queries {
tree.Update(q[0], q[1])
ans = (ans + tree.Query()) % MOD
}
return int(ans)
} type SegNode struct {
v00, v01, v10, v11 int64
} func NewSegNode() *SegNode {
return &SegNode{0, 0, 0, 0}
} func (sn *SegNode) Set(v int64) {
sn.v00, sn.v01, sn.v10 = 0, 0, 0
sn.v11 = int64(math.Max(float64(v), 0))
} func (sn *SegNode) Best() int64 {
return sn.v11
} type SegTree struct {
n int
tree []*SegNode
} func NewSegTree(n int) *SegTree {
tree := make([]*SegNode, n * 4 + 1)
for i := range tree {
tree[i] = NewSegNode()
}
return &SegTree{n, tree}
} func (st *SegTree) Init(nums []int) {
st.internalInit(nums, 1, 1, st.n)
} func (st *SegTree) Update(x, v int) {
st.internalUpdate(1, 1, st.n, x + 1, int64(v))
} func (st *SegTree) Query() int64 {
return st.tree[1].Best()
} func (st *SegTree) internalInit(nums []int, x, l, r int) {
if l == r {
st.tree[x].Set(int64(nums[l - 1]))
return
}
mid := (l + r) / 2
st.internalInit(nums, x * 2, l, mid)
st.internalInit(nums, x * 2 + 1, mid + 1, r)
st.pushup(x)
} func (st *SegTree) internalUpdate(x, l, r int, pos int, v int64) {
if l > pos || r < pos {
return
}
if l == r {
st.tree[x].Set(v)
return
}
mid := (l + r) / 2
st.internalUpdate(x * 2, l, mid, pos, v)
st.internalUpdate(x * 2 + 1, mid + 1, r, pos, v)
st.pushup(x)
} func (st *SegTree) pushup(x int) {
l, r := x * 2, x * 2 + 1
st.tree[x].v00 = max(st.tree[l].v00 + st.tree[r].v10, st.tree[l].v01 + st.tree[r].v00)
st.tree[x].v01 = max(st.tree[l].v00 + st.tree[r].v11, st.tree[l].v01 + st.tree[r].v01)
st.tree[x].v10 = max(st.tree[l].v10 + st.tree[r].v10, st.tree[l].v11 + st.tree[r].v00)
st.tree[x].v11 = max(st.tree[l].v10 + st.tree[r].v11, st.tree[l].v11 + st.tree[r].v01)
} func main() {
nums := []int{3,5,9}
queries := [][]int{{1,-2},{0,-3}}
result := maximumSumSubsequence(nums, queries)
fmt.Println(result)
}

Rust完整代码如下:

use std::cmp::max;

const MOD: i64 = 1_000_000_007;

#[derive(Clone)]
struct SegNode {
v00: i64,
v01: i64,
v10: i64,
v11: i64,
} impl SegNode {
fn new() -> Self {
SegNode {
v00: 0,
v01: 0,
v10: 0,
v11: 0,
}
} fn set(&mut self, v: i64) {
self.v00 = 0;
self.v01 = 0;
self.v10 = 0;
self.v11 = max(v, 0);
} fn best(&self) -> i64 {
self.v11
}
} struct SegTree {
n: usize,
tree: Vec<SegNode>,
} impl SegTree {
fn new(n: usize) -> Self {
let tree = vec![SegNode::new(); n * 4];
SegTree { n, tree }
} fn init(&mut self, nums: &[i32]) {
self.internal_init(nums, 1, 1, self.n);
} fn update(&mut self, pos: usize, v: i32) {
self.internal_update(1, 1, self.n, pos + 1, v as i64);
} fn query(&self) -> i64 {
self.tree[1].best()
} fn internal_init(&mut self, nums: &[i32], x: usize, l: usize, r: usize) {
if l == r {
self.tree[x].set(nums[l - 1] as i64);
return;
}
let mid = (l + r) / 2;
self.internal_init(nums, x * 2, l, mid);
self.internal_init(nums, x * 2 + 1, mid + 1, r);
self.push_up(x);
} fn internal_update(&mut self, x: usize, l: usize, r: usize, pos: usize, v: i64) {
if l > pos || r < pos {
return;
}
if l == r {
self.tree[x].set(v);
return;
}
let mid = (l + r) / 2;
self.internal_update(x * 2, l, mid, pos, v);
self.internal_update(x * 2 + 1, mid + 1, r, pos, v);
self.push_up(x);
} fn push_up(&mut self, x: usize) {
let l = x * 2;
let r = x * 2 + 1;
self.tree[x].v00 = max(
self.tree[l].v00 + self.tree[r].v10,
self.tree[l].v01 + self.tree[r].v00,
);
self.tree[x].v01 = max(
self.tree[l].v00 + self.tree[r].v11,
self.tree[l].v01 + self.tree[r].v01,
);
self.tree[x].v10 = max(
self.tree[l].v10 + self.tree[r].v10,
self.tree[l].v11 + self.tree[r].v00,
);
self.tree[x].v11 = max(
self.tree[l].v10 + self.tree[r].v11,
self.tree[l].v11 + self.tree[r].v01,
);
}
} fn maximum_sum_subsequence(nums: &[i32], queries: &[(usize, i32)]) -> i64 {
let n = nums.len();
let mut tree = SegTree::new(n);
tree.init(nums);
let mut ans = 0; for (x, v) in queries {
tree.update(*x, *v);
ans = (ans + tree.query()) % MOD;
} ans
} fn main() {
let nums = vec![3, 5, 9];
let queries = vec![(1, -2), (0, -3)];
let result = maximum_sum_subsequence(&nums, &queries);
println!("{}", result);
}

C完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h> #define MOD 1000000007 typedef struct {
long long v00, v01, v10, v11;
} SegNode; typedef struct {
int n;
SegNode* tree;
} SegTree; SegNode newSegNode() {
SegNode node;
node.v00 = 0;
node.v01 = 0;
node.v10 = 0;
node.v11 = 0;
return node;
} void setSegNode(SegNode* sn, long long v) {
sn->v00 = 0;
sn->v01 = 0;
sn->v10 = 0;
sn->v11 = fmax(v, 0);
} long long bestSegNode(SegNode* sn) {
return sn->v11;
} SegTree* newSegTree(int n) {
SegTree* tree = (SegTree*)malloc(sizeof(SegTree));
tree->n = n;
tree->tree = (SegNode*)malloc(sizeof(SegNode) * (4 * n + 1)); for (int i = 0; i < 4 * n + 1; i++) {
tree->tree[i] = newSegNode();
} return tree;
} void pushup(SegTree* st, int x); void internalInit(SegTree* st, int* nums, int x, int l, int r) {
if (l == r) {
setSegNode(&st->tree[x], (long long)nums[l - 1]);
return;
}
int mid = (l + r) / 2;
internalInit(st, nums, x * 2, l, mid);
internalInit(st, nums, x * 2 + 1, mid + 1, r);
pushup(st, x);
} void pushup(SegTree* st, int x) {
int l = x * 2;
int r = x * 2 + 1;
st->tree[x].v00 = fmax(st->tree[l].v00 + st->tree[r].v10, st->tree[l].v01 + st->tree[r].v00);
st->tree[x].v01 = fmax(st->tree[l].v00 + st->tree[r].v11, st->tree[l].v01 + st->tree[r].v01);
st->tree[x].v10 = fmax(st->tree[l].v10 + st->tree[r].v10, st->tree[l].v11 + st->tree[r].v00);
st->tree[x].v11 = fmax(st->tree[l].v10 + st->tree[r].v11, st->tree[l].v11 + st->tree[r].v01);
} void internalUpdate(SegTree* st, int x, int l, int r, int pos, long long v) {
if (l > pos || r < pos) {
return;
}
if (l == r) {
setSegNode(&st->tree[x], v);
return;
}
int mid = (l + r) / 2;
internalUpdate(st, x * 2, l, mid, pos, v);
internalUpdate(st, x * 2 + 1, mid + 1, r, pos, v);
pushup(st, x);
} long long query(SegTree* st) {
return bestSegNode(&st->tree[1]);
} void initSegTree(SegTree* st, int* nums) {
internalInit(st, nums, 1, 1, st->n);
} void updateSegTree(SegTree* st, int pos, int v) {
internalUpdate(st, 1, 1, st->n, pos + 1, v);
} long long maximumSumSubsequence(int* nums, int numsSize, int(*queries)[2], int queriesSize) {
SegTree* tree = newSegTree(numsSize);
initSegTree(tree, nums);
long long ans = 0; for (int i = 0; i < queriesSize; i++) {
updateSegTree(tree, queries[i][0], queries[i][1]);
ans = (ans + query(tree)) % MOD;
} // Free allocated memory
free(tree->tree);
free(tree);
return ans;
} int main() {
int nums[] = { 3, 5, 9 };
int queries[2][2] = { {1, -2}, {0, -3} };
long long result = maximumSumSubsequence(nums, 3, queries, 2);
printf("%lld\n", result);
return 0;
}

C++完整代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath> const int MOD = 1000000007; class SegNode {
public:
long long v00, v01, v10, v11; SegNode() : v00(0), v01(0), v10(0), v11(0) {} void set(long long v) {
v00 = 0;
v01 = 0;
v10 = 0;
v11 = std::max(v, 0LL);
} long long best() const {
return v11;
}
}; class SegTree {
private:
int n;
std::vector<SegNode> tree; void pushup(int x) {
int l = x * 2;
int r = x * 2 + 1;
tree[x].v00 = std::max(tree[l].v00 + tree[r].v10, tree[l].v01 + tree[r].v00);
tree[x].v01 = std::max(tree[l].v00 + tree[r].v11, tree[l].v01 + tree[r].v01);
tree[x].v10 = std::max(tree[l].v10 + tree[r].v10, tree[l].v11 + tree[r].v00);
tree[x].v11 = std::max(tree[l].v10 + tree[r].v11, tree[l].v11 + tree[r].v01);
} void internalInit(const std::vector<int>& nums, int x, int l, int r) {
if (l == r) {
tree[x].set(static_cast<long long>(nums[l - 1]));
return;
}
int mid = (l + r) / 2;
internalInit(nums, x * 2, l, mid);
internalInit(nums, x * 2 + 1, mid + 1, r);
pushup(x);
} void internalUpdate(int x, int l, int r, int pos, long long v) {
if (l > pos || r < pos) {
return;
}
if (l == r) {
tree[x].set(v);
return;
}
int mid = (l + r) / 2;
internalUpdate(x * 2, l, mid, pos, v);
internalUpdate(x * 2 + 1, mid + 1, r, pos, v);
pushup(x);
} public:
SegTree(int n) : n(n) {
tree.resize(n * 4);
} void init(const std::vector<int>& nums) {
internalInit(nums, 1, 1, n);
} void update(int pos, int v) {
internalUpdate(1, 1, n, pos + 1, static_cast<long long>(v));
} long long query() const {
return tree[1].best();
}
}; long long maximumSumSubsequence(const std::vector<int>& nums, const std::vector<std::pair<int, int>>& queries) {
int n = nums.size();
SegTree tree(n);
tree.init(nums);
long long ans = 0; for (const auto& query : queries) {
tree.update(query.first, query.second);
ans = (ans + tree.query()) % MOD;
} return ans;
} int main() {
std::vector<int> nums = { 3, 5, 9 };
std::vector<std::pair<int, int>> queries = { {1, -2}, {0, -3} };
long long result = maximumSumSubsequence(nums, queries);
std::cout << result << std::endl;
return 0;
}

Python完整代码如下:

# -*-coding:utf-8-*-

class SegNode:
def __init__(self):
self.v00 = 0
self.v01 = 0
self.v10 = 0
self.v11 = 0 def set(self, v):
self.v00 = 0
self.v01 = 0
self.v10 = 0
self.v11 = max(v, 0) def best(self):
return self.v11 class SegTree:
def __init__(self, n):
self.n = n
self.tree = [SegNode() for _ in range(n * 4 + 1)] def init(self, nums):
self._internal_init(nums, 1, 1, self.n) def update(self, x, v):
self._internal_update(1, 1, self.n, x + 1, v) def query(self):
return self.tree[1].best() def _internal_init(self, nums, x, l, r):
if l == r:
self.tree[x].set(nums[l - 1])
return
mid = (l + r) // 2
self._internal_init(nums, x * 2, l, mid)
self._internal_init(nums, x * 2 + 1, mid + 1, r)
self._pushup(x) def _internal_update(self, x, l, r, pos, v):
if l > pos or r < pos:
return
if l == r:
self.tree[x].set(v)
return
mid = (l + r) // 2
self._internal_update(x * 2, l, mid, pos, v)
self._internal_update(x * 2 + 1, mid + 1, r, pos, v)
self._pushup(x) def _pushup(self, x):
l, r = x * 2, x * 2 + 1
self.tree[x].v00 = max(self.tree[l].v00 + self.tree[r].v10, self.tree[l].v01 + self.tree[r].v00)
self.tree[x].v01 = max(self.tree[l].v00 + self.tree[r].v11, self.tree[l].v01 + self.tree[r].v01)
self.tree[x].v10 = max(self.tree[l].v10 + self.tree[r].v10, self.tree[l].v11 + self.tree[r].v00)
self.tree[x].v11 = max(self.tree[l].v10 + self.tree[r].v11, self.tree[l].v11 + self.tree[r].v01) MOD = 1000000007 def maximum_sum_subsequence(nums, queries):
n = len(nums)
tree = SegTree(n)
tree.init(nums) ans = 0
for q in queries:
tree.update(q[0], q[1])
ans = (ans + tree.query()) % MOD
return ans if __name__ == "__main__":
nums = [3, 5, 9]
queries = [[1, -2], [0, -3]]
result = maximum_sum_subsequence(nums, queries)
print(result)

2025-01-04:不包含相邻元素的子序列的最大和。用go语言,给定一个整数数组 nums 和一个由二维数组 queries 组成的查询列表,其中每个查询的格式为 queries[i] = [pos的更多相关文章

  1. 062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用

    062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用 本文知识点:二维数组应用 二维数组的声明和创建 ? 出现空指针异常 数组的名字指向数组的第 ...

  2. Java知识系统回顾整理01基础06数组06二维数组

    一.一维数组和二维数组 这是一个一维数组, 里面的每一个元素,都是一个基本类型int int a[] =new int[]{1,2,3,4,5}; 这是一个二维数组,里面的每一个元素,都是一个一维数组 ...

  3. PHP计算二维数组指定元素的和

    array_sum(array_column($arr, 'num')); //计算二维数组指定元素的和 $arr = [ [ 'id'=>1, 'num'=>3, ], [ 'id'=& ...

  4. JAVA描述算法和数据结构(01):稀疏数组和二维数组转换

    本文源码:GitHub·点这里 || GitEE·点这里 一.基本简介 1.基础概念 在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵:与之相反, ...

  5. 【剑指 Offer】04.二维数组中的查找

    题目描述 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...

  6. JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数

    JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数 示例如下 至少需要九个元素:"A","B","C",&q ...

  7. PHP代码篇(二)-- array_column函数将二维数组格式化成固定格式的一维数组,及优化查询方法

    小白因为经常用到多表查询,比如获取一个会员领取的卡卷list,里面当然包含了1“会员优惠券记录表t_coupon_members”主表,然后2“门店优惠券表t_coupon”,和3“门店信息表t_sh ...

  8. tp使用ajaxReturn返回二维数组格式的字符串,前台如何获取非乱码

    参考: https://www.cnblogs.com/jiqing9006/p/5000849.html https://blog.csdn.net/zengxiangxuan123456/arti ...

  9. Java练习小题_求一个3*3矩阵对角线元素之和,矩阵的数据用行的形式输入到计算机中 程序分析:利用双重for循环控制输入二维数组,再将a[i][i]累加后输出。

    要求说明: 题目:求一个3*3矩阵对角线元素之和,矩阵的数据用行的形式输入到计算机中 程序分析:利用双重for循环控制输入二维数组,再将 a[i][i] 累加后输出. 实现思路: [二维数组]相关知识 ...

  10. 06-01 Java 二维数组格式、二维数组内存图解、二维数组操作

    二维数组格式1 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的 ...

随机推荐

  1. 华为云-容器引擎CCE-部署Nginx应用

    环境准备 注册华为云账号 复制下面地址到浏览器地址栏(https://reg.huaweicloud.com/registerui/cn/register.html?fromacct=c76cea9f ...

  2. 掀起云端革命!ToDesk云电脑与传统PC电脑的差异分析

    在科技日新月异的今天,传统PC电脑的市场地位正悄然发生变化.随着云计算技术的不断成熟与普及,云电脑逐渐走进大众视野,不同于传统PC电脑的高昂的成本和易退化的硬件性能,云电脑正以其轻成本高性能的优势吸引 ...

  3. 《大话设计模式》java实现:第一章-简单工厂模式

    在<大话设计模式>中,示例代码使用C#实现,所以我这里使用Java实现一遍书中的设计模式. 第一章是使用简单工厂实现计算器. 遇到了一个问题:在Operation父类中,我们可以定义两个操 ...

  4. SSIS连接Excel2007版本之后的数据源

    今天我发现了新大陆,兴奋得不得了,由于原文写得太过详细与专业,我就偷偷懒直接Copy过来了,怕自己以后没地儿找,哈哈哈 原文链接:https://www.cnblogs.com/biwork/p/34 ...

  5. 最逼真的AI换脸软件,Pluse下载介绍(可直播)

    Pluse是基于人工智能的实时AI换脸工具,可以在无需任何前期数据训练的情况下,通过一张照片快速替换视频中的人脸,它支持高分辨率细节重建.色彩矫正,并能实时替换多目标人脸,非常适合娱乐社交.影视制作和 ...

  6. linux基本指令总结

    拖了好久的linux学习,终于开始啦 环境终于没问题了 边学边总结 一.常用指令 1.1 关机与开机 poweroff 马上关机 reboot 马上重启 1.2 目录文件操作命令 cd / 切换到根目 ...

  7. 记录一下opencv-contrib的编译使用

    一.来由 公司需求进行多图拼接算法,在opencv提供的Stitcher类当中默认的算子是ORB,我想尝试使用SIFT和SURF算子,经过一番查找发现这两个算子需要opencv的超集库支持--&quo ...

  8. downloadFile:base64数据导出文件,文件下载

    function downloadFile(filename, data){ let DownloadLink = document.createElement('a'); if ( Download ...

  9. SpringBoot进阶教程(八十三)Kaptcha

    Kaptcha是谷歌开源的一个可高度配置的比较老旧的实用验证码生成工具.它可以实现:(1)验证码的字体/大小颜色:(2)验证码内容的范围(数字,字母,中文汉字):(3)验证码图片的大小,边框,边框粗细 ...

  10. 微服务探索之路05篇jenkins构建net6和vue docker镜像到Harbor自动更新k8s服务镜像

    从1-4篇已经学习了docker Harbor k8s的基本用法.接下来进阶一下使用jenkins结合起来做到自动部署项目. 1 安装jenkins 1.1前提条件 docker环境,可参考第01篇安 ...