当前位置: 首页 > news >正文

Kimi LeetCode 3901. 好子序列查询 Python3实现

根据搜索结果,LeetCode 3901「好子序列查询」的 Python3 实现如下:

---

思路

1. 只关心 p 的倍数:如果 `nums[i]` 不是 `p` 的倍数,它对 GCD 为 `p` 的子序列没有贡献,在线段树中视为 `0`。
2. 线段树维护所有 p 倍数的 GCD:记为 `g`。
- 若 `g != p`,则不存在好子序列。
- 若 `g == p`,则所有 p 的倍数整体 GCD 已是 `p`。
3. 长度严格小于 n:
- 若 `cnt < n`(并非所有元素都是 p 的倍数),直接取所有 p 的倍数即可,长度必然 `< n`。
- 若 `cnt == n`(所有元素都是 p 的倍数),需要删一个元素后 GCD 仍为 `p`。
- 关键结论:若 `n > 6` 且整体 GCD 为 `p`,则一定可以删一个元素使 GCD 仍为 `p`。因此只需在 `n <= 6` 时暴力枚举删除位置。
4. 线段树操作:单点更新、区间查询 GCD。

---

Python3 实现

```python
from math import gcd

class Node:
__slots__ = "l", "r", "g"

def __init__(self, l: int, r: int):
self.l = l
self.r = r
self.g = 0

class SegmentTree:
__slots__ = "tr"

def __init__(self, n: int):
self.tr: list[Node | None] = [None] * (n << 2)
self.build(1, 1, n)

def build(self, u: int, l: int, r: int):
self.tr[u] = Node(l, r)
if l == r:
return
mid = (l + r) >> 1
self.build(u << 1, l, mid)
self.build(u << 1 | 1, mid + 1, r)

def pushup(self, u: int):
self.tr[u].g = gcd(self.tr[u << 1].g, self.tr[u << 1 | 1].g)

def modify(self, u: int, x: int, v: int):
if self.tr[u].l == self.tr[u].r:
self.tr[u].g = v
return
mid = (self.tr[u].l + self.tr[u].r) >> 1
if x <= mid:
self.modify(u << 1, x, v)
else:
self.modify(u << 1 | 1, x, v)
self.pushup(u)

def query(self, u: int, l: int, r: int) -> int:
if l > r:
return 0
if self.tr[u].l >= l and self.tr[u].r <= r:
return self.tr[u].g
mid = (self.tr[u].l + self.tr[u].r) >> 1
if r <= mid:
return self.query(u << 1, l, r)
if l > mid:
return self.query(u << 1 | 1, l, r)
return gcd(self.query(u << 1, l, mid), self.query(u << 1 | 1, mid + 1, r))

class Solution:
def countGoodSubseq(self, nums: list[int], p: int, queries: list[list[int]]) -> int:
n = len(nums)
tree = SegmentTree(n)
cnt = 0

for i, x in enumerate(nums, 1):
if x % p == 0:
tree.modify(1, i, x)
cnt += 1

ans = 0
for idx, val in queries:
if nums[idx] % p == 0:
tree.modify(1, idx + 1, 0)
cnt -= 1
if val % p == 0:
tree.modify(1, idx + 1, val)
cnt += 1
nums[idx] = val

if tree.tr[1].g != p:
continue

if cnt < n or n > 6:
ans += 1
continue

for i in range(1, n + 1):
left_g = tree.query(1, 1, i - 1)
right_g = tree.query(1, i + 1, n)
if gcd(left_g, right_g) == p:
ans += 1
break

return ans
```

---

复杂度

- 时间复杂度:O((n + q) \times \log n),其中 n \le 6 时的暴力枚举是常数级。
- 空间复杂度:O(n)。

http://www.jsqmd.com/news/1392435/

相关文章:

  • gcc编译器,以及源文件的翻译
  • 如何筛选靠谱的线上投票平台?2026年全场景通用投票工具深度评测
  • 从英语到斯瓦希里语,AI功能机的多语言适配怎么做?
  • POB汉化工具 PoeCharm 完整上手:3步安装与天赋技能配置实测
  • AI-实践 开发日志
  • 中国路况,中国速度——佳研 AI 让汽车碰撞仿真不再“卡脖子” - 2027品牌AI展
  • AI论文指令大合集:deepseek,kimi,豆包等各AI工具齐齐发力,轻松搞定论文写作难题
  • Databricks中用PySpark找到表里的最短唯一键
  • notepad-- 文件对比实战指南:3 步上手差异比对,5 个技巧让代码核查快 10 倍
  • TVA-具身智能最新进展(3):主动视觉感知提升实时性
  • 个体自发用 AI 提效已是职场常态,企业统一推进为何反而频频遇阻
  • 武汉江夏初中毕业生技术学校推荐 i3D AI 三维专业本地可参观试学 - 荆楚笔记
  • GHelper完整使用指南:如何用一个轻量小工具接管华硕笔记本性能控制
  • 合并报表系统有哪些?6家服务商能力对比与选型建议
  • Windows Defender 移除完整指南:三档移除深度与一次 ISO 实战演示
  • OpenBMC:WebUI 与后端接口交互流程
  • OneNote 笔记搬家到 Markdown:用 onenote-md-exporter 一劳永逸的完整教程
  • 【GitOps·入门篇】工具生态:ArgoCD、Flux、Jenkins X 对比选型
  • 2026年智慧步道建设指南:从硬件到运营的全链路解析
  • 聊天记录都在,模型为什么还是会“忘记”?
  • 基于 Java Web 的在线学习教育平台管理系统的设计与实现-----附源码85799-----课程、报名、考试与教学管理的一体化实现
  • TypeScript 灵魂拷问:type 和 interface 到底怎么选?
  • 闲置盒马卡别吃亏!2026年详解盒马卡回收一般几折 - 京顺回收
  • 山东本地综合实力强的职业院校推荐:选校时值得关注的几个维度 - 2027品牌AI展
  • 从一句主题到一支成片:Pixelle-Video 零门槛全自动短视频引擎
  • 视觉自动化测试新范式:用Midscene.js让AI替你点遍全平台界面
  • 告别报错弹窗!NDI Runtime 修复的 8 步阶梯式自救指南(DistroAV 新手向)
  • BarTender提示#807错误:无法在拥有其他许可证的LicensingService上激活节点锁定的 Professional 版许可证 的解决办法
  • 设计高效的 Agentic AI Workflows:从企业流程到 Agent 执行图
  • 2026年福建3D床垫厂家 选品迷茫 适配多需求参考 - 甄选测评馆