Kimi    LeetCode 3525. 求出数组的 X 值 II Go实现 以下是 LeetCode 3525 求出数组的 X 值 II 的 Go 实现核心思路是线段树维护区间前缀积的模分布。思路概述- 对于每个查询先单点修改 nums[index]再移除前缀保留 [start..]最后可以删除任意后缀即保留任意非空前缀。- 因此每个查询的答案等价于在子数组 nums[start..] 的所有非空前缀中乘积模 k 等于 x 的个数。- 由于 k ≤ 5线段树每个节点只需维护- prod区间整体乘积模 k- cntcnt[m] 表示该区间内有多少个非空前缀的乘积模 k 等于 m- 合并两个子区间时右子树的前缀需要乘上左子树的总积再模 k。复杂度- 时间O((n q) · k² · log n)由于 k ≤ 5实际约为 O((n q) log n)- 空间O(n)完整代码gotype Node struct {prod int // 区间乘积 % kcnt [5]int // cnt[m] 非空前缀中乘积 % k m 的个数}type SegTree struct {k inttree []Noden int}func NewSegTree(nums []int, k int) *SegTree {n : len(nums)seg : SegTree{k: k,tree: make([]Node, n*4),n: n,}seg.build(1, 0, n-1, nums)return seg}func (s *SegTree) build(node, l, r int, nums []int) {if l r {v : nums[l] % s.ks.tree[node].prod vs.tree[node].cnt [5]int{}s.tree[node].cnt[v] 1return}mid : (l r) 1s.build(node1, l, mid, nums)s.build(node1|1, mid1, r, nums)s.pull(node)}func (s *SegTree) merge(left, right Node) Node {var res Noderes.prod (left.prod * right.prod) % s.k// 左区间的前缀直接保留for i : 0; i s.k; i {res.cnt[i] left.cnt[i]}// 右区间的前缀需要乘上左区间的总积for i : 0; i s.k; i {if right.cnt[i] ! 0 {newMod : (left.prod * i) % s.kres.cnt[newMod] right.cnt[i]}}return res}func (s *SegTree) pull(node int) {s.tree[node] s.merge(s.tree[node1], s.tree[node1|1])}func (s *SegTree) update(node, l, r, idx, val int) {if l r {v : val % s.ks.tree[node].prod vs.tree[node].cnt [5]int{}s.tree[node].cnt[v] 1return}mid : (l r) 1if idx mid {s.update(node1, l, mid, idx, val)} else {s.update(node1|1, mid1, r, idx, val)}s.pull(node)}func (s *SegTree) query(node, l, r, ql, qr int) Node {if ql l r qr {return s.tree[node]}mid : (l r) 1if qr mid {return s.query(node1, l, mid, ql, qr)}if ql mid {return s.query(node1|1, mid1, r, ql, qr)}left : s.query(node1, l, mid, ql, qr)right : s.query(node1|1, mid1, r, ql, qr)return s.merge(left, right)}func resultArray(nums []int, k int, queries [][]int) []int {n : len(nums)for i : range nums {nums[i] % k}seg : NewSegTree(nums, k)ans : make([]int, 0, len(queries))for _, q : range queries {idx, val, start, x : q[0], q[1]%k, q[2], q[3]seg.update(1, 0, n-1, idx, val)res : seg.query(1, 0, n-1, start, n-1)ans append(ans, res.cnt[x])}return ans}关键点说明1. cnt 的含义每个节点维护的是从该区间左端点开始的所有非空前缀的模分布。这样查询任意子区间时递归返回的子节点天然满足从左端点开始的要求合并时只需把右子树的前缀乘上左子树的总积即可。2. k ≤ 5 的利用cnt 数组固定开 5实际只用前 k 个合并时的双重循环最多 25 次运算常数极小。3. 单点更新修改叶子后自底向上 pull保持每个节点的 prod 和 cnt 正确。4. 预处理取模建树前和更新时都把数值对 k 取模避免大数运算。

相关新闻

最新新闻

人形机器人第一股背后:仿真、数据闭环与垂直场景的技术真相

人形机器人第一股背后:仿真、数据闭环与垂直场景的技术真相

“人形机器人第一股启动询价”这条新闻,表面看是资本市场的IPO事件,本质上却是整个行业的定价时刻。当一家公司被冠上“第一股”的名头时,它不只是给自己估值,也是在替整个技术赛道回答一个问题:人形机器人到底值多少钱…

2026/8/28 1:19:08
MyEclipse 常用设置与快捷功能大全

MyEclipse 常用设置与快捷功能大全

一、工具优化以下为 MyEclipse 开发环境的基础优化设置,涵盖编码、字体、插件等常用配置。修改当前工作区下所有项目编码:Window->Preferences->General->Workspace->Text File Encoding改为UTF-8修改当前项目编码:项目->右键…

2026/8/28 1:19:08
存储芯片研报拆解指南:用Python识别市场预期与基本面的背离信号

存储芯片研报拆解指南:用Python识别市场预期与基本面的背离信号

存储芯片行业最近几年始终处于高波动状态:市场传闻、库存数据、价格指数和财报预期经常同时给出互相矛盾的信号。当一份 21 页的研究报告把存储芯片的八大问题拆开,结论往往不是简单的看多或看空,而是提醒读者:市场交易的是预期转…

2026/8/28 1:19:08
从2048游戏到MDP建模:数学建模竞赛中的启发式搜索与MATLAB实现

从2048游戏到MDP建模:数学建模竞赛中的启发式搜索与MATLAB实现

1. 项目概述:从游戏到数学模型的跨越“2048”这款游戏,相信很多朋友都玩过,甚至为之着迷过。滑动屏幕,合并数字,目标直指那个看似遥不可及的2048方块。但你是否想过,这个简单的滑动合并游戏背后&#xff0c…

2026/8/28 1:19:08
模型后训练三阶段全景:预训练、SFT(监督微调)与RL(强化学习)的本质区别

模型后训练三阶段全景:预训练、SFT(监督微调)与RL(强化学习)的本质区别

15-模型后训练三阶段全景:预训练、SFT(监督微调)与RL(强化学习)的本质区别系列导读:前两篇聊的是"怎么评估",这一篇进入"怎么变强"。基于李博杰《深入理解AI Agent&#xf…

2026/8/28 1:19:08
【路径规划】使用 STOMP 进行路径规划和优化附Matlab代码

【路径规划】使用 STOMP 进行路径规划和优化附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/28 1:14:08