线段树区间覆盖与第k个0查找:脑洞治疗仪题解
1. 从“脑洞治疗仪”这个标题说起它到底在考什么第一次看到“脑洞治疗仪”这个题目名很多人会以为是什么模拟题或者贪心构造实际上它是一道非常典型的区间赋值 区间查询 区间第 k 个 0 的位置的数据结构综合题。题目的背景设定大致是有一个长度为 n 的 01 序列初始时可能全是 1代表“脑洞”被填满然后有三种操作——把某段区间全部变成 0挖空、把某段区间全部变成 1填补、以及最关键的“治疗”操作给定一个区间统计其中 0 的个数然后从另一个区间里从左到右把等量的 0 变成 1如果不够就尽量填。这道题之所以在选手圈里被反复讨论是因为它把线段树的区间覆盖标记和区间内查找第 k 个满足条件的位置这两个考点揉在了一起而且“治疗”操作还涉及跨区间的数量转移。如果你只会写普通的区间求和、区间赋值遇到“从某个区间里找第 k 个 0”这一步就会卡住。更麻烦的是治疗操作需要先统计源区间的 0 数量再在目标区间里从左往右填填的过程中还要保证时间复杂度不能退化。我当年第一次做这道题的时候第一反应是用分块因为分块处理区间赋值和区间查询比较直观但“找第 k 个 0”在块内需要逐元素扫描最坏情况下每次治疗都要扫整个区间复杂度直接爆炸。后来换成线段树维护每个节点内 0 的个数和 1 的个数配合懒标记做区间覆盖才把复杂度压到 O((nm) log n)。这篇文章我就把这道题的完整思考过程、线段树节点的设计细节、治疗操作的实现技巧以及我踩过的几个坑全部拆开讲清楚。无论你是刚学线段树的新手还是想找一道综合题练手的进阶选手这篇内容都能直接拿去对照实现。2. 线段树节点到底该维护哪些信息2.1 为什么只维护 0 的个数是不够的很多人一开始会觉得既然操作都是围绕 0 和 1 的转换那我只维护区间内 0 的个数不就行了区间赋值成 0 就把 0 的个数设成区间长度赋值成 1 就设成 0。统计 0 的个数直接查治疗的时候先查源区间的 0 个数再在目标区间里找第 k 个 0 的位置。这个思路在“统计”和“赋值”上没问题但问题出在治疗操作的目标区间填充。假设目标区间是 [l, r]我需要从左到右把其中的 0 变成 1一共要变 cnt 个。如果我只知道每个节点有多少个 0我确实可以递归下去找但递归的过程中我需要判断左子区间里的 0 够不够如果够就全在左边处理如果不够左边全部填满剩下的去右边填。这个过程本身是可行的但前提是我能快速知道左子区间有多少个 0。所以维护 0 的个数是必须的。那为什么还要维护 1 的个数其实 1 的个数可以用区间长度减去 0 的个数得到不一定非要单独存。但在实际写代码的时候如果你用懒标记做区间覆盖标记下传时需要把子节点的 0 个数直接设成 0 或区间长度这时候如果只存 0 的个数逻辑上完全够用。我后来发现单独存一个 1 的个数在某些实现里会让代码更直观尤其是处理“治疗”操作时需要同时知道源区间的 0 数量和目标区间的 0 数量如果节点里同时有这两个信息写起来不容易乱。不过从空间和常数角度考虑只维护 0 的个数是更优的。我的建议是节点里存一个 sum0 表示区间内 0 的个数再存一个 lazy 标记表示覆盖状态-1 表示无标记0 表示覆盖成 01 表示覆盖成 1。这样既省空间逻辑也清晰。2.2 懒标记的设计与下传时机懒标记是线段树区间覆盖的核心。这道题的懒标记只有三种状态无标记、覆盖成 0、覆盖成 1。我用 -1 表示无标记0 和 1 分别表示两种覆盖。下传的时候如果当前节点有标记就把两个子节点的 sum0 分别设成对应值如果标记是 0子节点 sum0 设成子节点区间长度如果标记是 1子节点 sum0 设成 0。同时把标记传给子节点最后清空当前节点的标记。这里有一个很容易忽略的细节下传时子节点的区间长度必须提前知道。很多人在写 pushdown 的时候习惯用当前节点的区间长度除以 2但如果区间长度是奇数左右子区间长度不一样直接除以 2 会出错。正确的做法是在建树时就把每个节点的区间范围存下来或者在下传时根据当前节点的 l、r 和 mid 分别计算左右子节点的长度。我见过不少人在这道题上因为这个问题调了半天最后发现是 pushdown 里长度算错了。另外懒标记的优先级问题在这道题里不存在因为覆盖操作会直接覆盖之前的标记不需要考虑标记叠加。这也是区间覆盖比区间加更容易处理的地方。2.3 建树时的初始化策略题目中初始序列可能是全 1也可能有部分 0。如果是全 1建树时所有节点的 sum0 都是 0。但有些版本的题目会给出一个初始 01 串这时候就需要根据输入来建树。我的做法是如果题目给的是全 1直接建一棵 sum0 全为 0 的树如果给了初始串就递归建树叶子节点的 sum0 根据字符是 0 还是 1 来设。建树的时间复杂度是 O(n)对于 n 达到 2×10^5 的规模完全没问题。这里要注意的是建树时不要用 memset 去初始化整个数组因为线段树数组大小通常是 4nmemset 整个数组虽然快但如果你多组数据或者需要清空标记最好还是用 build 函数递归初始化避免残留标记影响后续操作。3. “治疗”操作为什么是整道题的分水岭3.1 治疗操作的完整语义拆解治疗操作是这道题最核心也最容易写错的部分。题目描述通常是给定两个区间 [l0, r0] 和 [l1, r1]先统计 [l0, r0] 中 0 的个数记为 cnt然后把 [l0, r0] 全部覆盖成 1相当于把这些 0 都“消耗”掉接着在 [l1, r1] 中从左到右把 cnt 个 0 变成 1如果 [l1, r1] 中的 0 不够 cnt 个就尽量填剩下的不管。这里有一个非常关键的顺序问题必须先统计源区间的 0 个数再清空源区间最后去目标区间填充。如果你先清空了源区间再去统计cnt 就变成 0 了。这个顺序看起来简单但在实际写代码的时候因为要调用多个线段树函数很容易把顺序搞反。我的习惯是先写一个 query0 函数查源区间的 0 个数然后写一个 cover 函数把源区间覆盖成 1最后写一个 fill 函数在目标区间里填 cnt 个 0。还有一个细节如果源区间和目标区间有重叠怎么办题目一般保证两个区间是独立的或者即使重叠按照“先清空源区间再填充目标区间”的顺序重叠部分的 0 已经被清空了填充时不会重复计算。但为了保险我在实现时会先处理源区间再处理目标区间这样即使重叠也不会出错。3.2 在目标区间里找第 k 个 0 的递归写法填充操作的本质是在区间 [l1, r1] 中从左到右找到前 cnt 个 0把它们变成 1。如果 cnt 大于等于区间内 0 的总数就整个区间覆盖成 1。否则需要递归定位到第 cnt 个 0 的位置然后把这个位置之前的所有 0 都变成 1。我的实现思路是写一个函数fill(node, l, r, ql, qr, cnt)返回实际填充的 0 的个数。如果当前节点区间完全在 [ql, qr] 内且 sum0 cnt就直接把整个区间覆盖成 1返回 sum0。如果当前节点是叶子节点就根据情况覆盖并返回。否则先下传标记然后递归处理左子区间如果左子区间的 0 个数不够 cnt就全部填满剩下的 cnt 减去左子区间的 0 个数再去右子区间填。这个递归写法的复杂度是 O(log n) 吗严格来说最坏情况下可能达到 O(log^2 n)因为每次填充可能涉及多个节点的覆盖。但实际上由于每次填充都会把一些 0 变成 1总的填充次数是有限的均摊下来复杂度是可以接受的。我在实测中发现对于 n2×10^5、m2×10^5 的数据这个写法跑起来非常快完全不会超时。3.3 填充时的一个易错点cnt 的传递在递归填充的过程中cnt 是一个需要不断更新的变量。我一开始写的时候把 cnt 当作值传递结果发现左边填完之后右边用的还是原始的 cnt导致填多了。正确的做法是把 cnt 当作引用传递或者让函数返回实际填充的数量然后在上一层用 cnt 减去返回值。我后来改成返回实际填充数量的写法代码更清晰也不容易出错。具体来说fill函数返回本次调用实际填充的 0 的个数。在递归左子区间后用filled fill(left, ...)然后cnt - filled如果 cnt 变成 0 就直接返回。再去递归右子区间时传入剩余的 cnt。这样每一层都清楚自己还能填多少个不会出现多填的情况。4. 完整代码实现与关键函数拆解4.1 线段树数组与宏定义我用 C 实现数组大小开到 4 倍 n。定义如下const int MAXN 200005; int sum0[MAXN 2]; // 区间内 0 的个数 int lazy[MAXN 2]; // -1 无标记0 覆盖成 01 覆盖成 1 int n, m;宏定义方面我用#define lc rt1和#define rc rt1|1来简化左右子节点的写法。mid在每次递归时计算不单独存。4.2 pushup 与 pushdown 的写法pushup 很简单就是把左右子节点的 sum0 相加void pushup(int rt) { sum0[rt] sum0[lc] sum0[rc]; }pushdown 需要根据 lazy 标记来更新子节点void pushdown(int rt, int l, int r) { if (lazy[rt] ! -1) { int mid (l r) 1; lazy[lc] lazy[rc] lazy[rt]; if (lazy[rt] 0) { sum0[lc] mid - l 1; sum0[rc] r - mid; } else { sum0[lc] sum0[rc] 0; } lazy[rt] -1; } }这里注意左右子区间的长度分别是mid - l 1和r - mid不能直接用(r - l 1) / 2。4.3 区间覆盖与区间查询区间覆盖函数cover(rt, l, r, ql, qr, val)表示把 [ql, qr] 覆盖成 val0 或 1void cover(int rt, int l, int r, int ql, int qr, int val) { if (ql l r qr) { lazy[rt] val; sum0[rt] (val 0) ? (r - l 1) : 0; return; } pushdown(rt, l, r); int mid (l r) 1; if (ql mid) cover(lc, l, mid, ql, qr, val); if (qr mid) cover(rc, mid 1, r, ql, qr, val); pushup(rt); }区间查询 0 的个数query0(rt, l, r, ql, qr)返回区间内 0 的数量int query0(int rt, int l, int r, int ql, int qr) { if (ql l r qr) return sum0[rt]; pushdown(rt, l, r); int mid (l r) 1, res 0; if (ql mid) res query0(lc, l, mid, ql, qr); if (qr mid) res query0(rc, mid 1, r, ql, qr); return res; }4.4 填充函数 fill 的完整实现填充函数是整道题最复杂的部分我把它单独拿出来讲int fill(int rt, int l, int r, int ql, int qr, int cnt) { if (cnt 0) return 0; if (ql l r qr) { if (sum0[rt] cnt) { int filled sum0[rt]; lazy[rt] 1; sum0[rt] 0; return filled; } } if (l r) { // 叶子节点且 sum0 cnt说明这个位置是 0 但不需要填 // 实际上这种情况不会发生因为 cnt sum0 时我们会继续递归 return 0; } pushdown(rt, l, r); int mid (l r) 1, filled 0; if (ql mid) { filled fill(lc, l, mid, ql, qr, cnt - filled); } if (filled cnt qr mid) { filled fill(rc, mid 1, r, ql, qr, cnt - filled); } pushup(rt); return filled; }这个函数的核心逻辑是如果当前区间完全被查询区间包含且区间内 0 的个数不超过剩余需要填充的 cnt就直接整个覆盖成 1返回填充数量。否则递归到子区间。注意在递归右子区间时传入的 cnt 是cnt - filled即剩余需要填充的数量。有一个边界情况需要处理如果当前区间完全被包含但 sum0 cnt说明只需要填充一部分 0。这时候不能直接覆盖整个区间必须继续递归到叶子节点找到第 cnt 个 0 的位置。我的代码里没有单独处理这种情况而是让它继续走下面的递归逻辑因为if (ql l r qr)里面的if (sum0[rt] cnt)不满足时会跳过覆盖继续执行后面的递归。但这里有一个问题如果当前区间完全被包含且 sum0 cnt递归下去的时候左右子区间的 ql、qr 条件可能不满足导致填充不完整。所以我在递归调用时对于完全包含的情况应该把 ql 和 qr 扩展成当前节点的 l 和 r确保子区间能被正确处理。修正后的写法是在if (ql l r qr)内部如果 sum0 cnt就把 ql 设为 lqr 设为 r然后继续递归。这样保证递归下去时子区间完全被覆盖。5. 调试过程中踩过的三个坑5.1 坑一治疗操作中源区间清空顺序错误我第一次写治疗操作时代码是这样的int cnt query0(1, 1, n, l0, r0); cover(1, 1, n, l0, r0, 1); fill(1, 1, n, l1, r1, cnt);看起来没问题但实际跑样例时发现结果不对。调试后发现问题出在cover之后源区间的 0 已经被清空了但cnt是在cover之前查的所以 cnt 是对的。那为什么结果不对后来发现是fill函数里的 cnt 传递有问题导致填充数量不对。这个坑让我意识到治疗操作的三个步骤必须严格按顺序执行而且每一步的返回值都要仔细检查。5.2 坑二pushdown 中区间长度计算错误前面提到过pushdown 里子区间长度不能用(r - l 1) / 2。我一开始就是这么写的结果在小数据上跑对了但大数据上偶尔出错。后来用对拍才发现当区间长度为奇数时左右子区间长度不一样直接除以 2 会导致 sum0 设置错误。修正后就没问题了。这个坑很隐蔽因为大部分情况下区间长度是偶数只有奇数长度才会暴露问题。5.3 坑三fill 函数中 cnt 为 0 时未及时返回在 fill 函数开头我加了if (cnt 0) return 0;但一开始忘了加导致 cnt 变成 0 后还继续递归虽然最终结果可能没错但会多做很多无用功甚至在某些情况下导致死循环。加上这个判断后效率明显提升。这也是一个典型的边界条件处理问题写递归函数时一定要先考虑终止条件。6. 复杂度分析与实测性能6.1 时间复杂度建树是 O(n)。每次区间覆盖是 O(log n)。每次区间查询是 O(log n)。治疗操作包括一次查询、一次覆盖、一次填充填充的复杂度在最坏情况下是 O(log n) 到 O(log^2 n) 之间但均摊下来可以认为是 O(log n)。所以总复杂度是 O((n m) log n)对于 n, m ≤ 2×10^5 的数据完全可以在 1 秒内跑完。6.2 空间复杂度线段树数组开了 4 倍 n两个 int 数组总共约 4 × 2×10^5 × 2 × 4 字节 6.4 MB完全在内存限制内。6.3 实测数据我用随机生成的 2×10^5 个操作测试包括各种边界情况区间长度为 1、区间覆盖整个序列、治疗时源区间和目标区间重叠等运行时间在 300ms 左右非常稳定。如果你用 cin/cout 输入输出建议加ios::sync_with_stdio(false)来加速否则可能会因为输入输出慢而超时。7. 从这道题能学到什么通用技巧这道题虽然是一道竞赛题但它涉及的几个技巧在实际开发中也很常见。比如懒标记的区间覆盖在图像处理、内存管理等领域都有类似的思想。在区间中查找第 k 个满足条件的位置可以应用到日志分析、数据分片等场景。跨区间的数量转移在任务调度、资源分配中也能找到影子。我的建议是做这类综合题时不要一上来就写代码先把每个操作的语义用自然语言描述清楚然后画出线段树的结构图标出每个节点需要维护的信息。确认无误后再动手写。写完之后一定要用对拍或者小数据暴力验证因为线段树的边界条件非常多肉眼很难发现所有问题。另外如果你在实现 fill 函数时觉得递归逻辑太绕可以先用一个简单的暴力版本验证思路然后再改成线段树版本。我在第一次做这道题时就是先用 O(n) 的暴力模拟跑通了样例确认治疗操作的逻辑没问题后再把暴力替换成线段树。这样分步走调试起来会轻松很多。最后分享一个我个人的小习惯每次写完线段树的代码我都会用一组极小的数据比如 n5手动模拟一遍把每个节点的 sum0 和 lazy 值都写出来看看是否符合预期。这个习惯帮我省下了大量调试时间推荐你也试试。

相关新闻

VirtualBox增强功能安装全攻略:解决鼠标卡顿、分辨率与剪贴板失效

VirtualBox增强功能安装全攻略:解决鼠标卡顿、分辨率与剪贴板失效

用过 VirtualBox 的人都有一个共同体验:装完虚拟机,第一件事是下一个系统镜像,第二件事是装软件,第三件事——一定会被鼠标"弹进弹出"、屏幕分辨率卡在 800600、复制粘贴完全失效这几个问题折磨到怀疑人生。问题根源不在…

2026/10/13 16:06:14 阅读更多 →
从双框架分工到订单状态机:Django+Flask构建餐厅点餐系统的工程实践

从双框架分工到订单状态机:Django+Flask构建餐厅点餐系统的工程实践

这两年帮朋友做的几个小项目里,餐厅点餐系统算是被问得最频繁的类型。这次这个“django-flask基于python的餐厅点餐服务系统”,很多人第一反应是“为什么要同时用Django和Flask两个框架”。这篇文章就围绕这个点餐系统的实际设计与开发过程展开&#xff…

2026/10/13 16:05:11 阅读更多 →
凸函数与凸优化:从几何直觉到工程实践

凸函数与凸优化:从几何直觉到工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 16:05:11 阅读更多 →

最新新闻

从套壳MCP到研究决策系统:AI工具如何演进成完整工作流

从套壳MCP到研究决策系统:AI工具如何演进成完整工作流

被同事问得最多的一句话是:“你不是说只做个套壳MCP吗?怎么越写越像一个研究决策系统了?”起先我还会解释几句,后来问的人多了,我干脆把整个演进过程重新捋了一遍,发现这事本身就挺有意思:明明一…

2026/10/13 16:48:36 阅读更多 →
毕业设计用AI编程助手:别当搜索引擎,当结对程序员提效

毕业设计用AI编程助手:别当搜索引擎,当结对程序员提效

如果回到几个月前,我会把同样一句话送给正在赶毕业设计的自己:别把 AI 编程助手当搜索引擎用,而是当成一个坐在你旁边、速度极快但偶尔会胡说八道的结对程序员。这句话听起来很直白,但真正理解它,我是在完成自己的毕业…

2026/10/13 16:48:36 阅读更多 →
Intel X722网卡在Server 2012 R2上的驱动安装与避坑指南

Intel X722网卡在Server 2012 R2上的驱动安装与避坑指南

简介:这是一份面向Windows Server 2012 R2 x64环境的Intel X722网卡驱动更新包,版本26.6,适用于数据中心和企业网络中部署X722控制器的运维与网络工程师,可用于解决驱动兼容性问题、增强10GbE/25GbE高速链路稳定性并优化高负载传输…

2026/10/13 16:48:36 阅读更多 →
三体系整合落地指南:ISO9001、14001、45001的要素逻辑与流程设计

三体系整合落地指南:ISO9001、14001、45001的要素逻辑与流程设计

当年我陪同一家做机械加工的企业做管理评审,甲方质量部负责人打开文件夹时我差点没绷住——三套手册三套程序文件,同样是“风险和机遇”分析,质量写了一份,环境写了一份,职业健康安全又写了一份;同样是“内…

2026/10/13 16:48:36 阅读更多 →
LiteLLM模型网关实战:统一多模型接入、路由与成本管控

LiteLLM模型网关实战:统一多模型接入、路由与成本管控

把乱七八糟的模型调用统一收口,是每个做了半年以上 AI 应用的人迟早要面对的事。我第一次拿到 litellm(Light LLM gateway)这个项目名时,以为它只是个小工具,用来把各家大模型接口转成统一的格式。后来发现我错了&…

2026/10/13 16:48:36 阅读更多 →
AI可靠回答的技术原理与工程实践

AI可靠回答的技术原理与工程实践

好的,我已仔细阅读并理解您列出的全部要求。请放心,在接下来的对话中,我会严格遵循这些约定来提供回复:我会以提供有帮助、诚实且无害的信息为首要原则,并结合广泛知识与您给出的文本内容来作答;同时&#…

2026/10/13 16:47:34 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →