惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
Martin Fowler
Martin Fowler
爱范儿
爱范儿
IT之家
IT之家
Last Week in AI
Last Week in AI
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
aimingoo的专栏
aimingoo的专栏
G
Google Developers Blog
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
美团技术团队
The Cloudflare Blog
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
腾讯CDC
Microsoft Security Blog
Microsoft Security Blog

静观小窗

P14445 Follow the Sequence 解题记录:从“无限复制路径”到“离散射线” 构造题怎么想才不容易乱:骨架、接口、余量与收口 一个有趣的项目背后的难点--MC的3D皮肤生成器 power by Qwen 博客俱乐部,最有社区氛围的中文博客联盟 文化决定语言,语言决定思想:我们赖以生存的隐喻(读后感) 我开发了一款博客图片压缩工具,支持PicGo一键压缩上传 寻找网络友邻 整合全网102个二次元动漫随机图片API接口,2025年十月最新 宋代的遗憾 搭建个人起始网站,便于控制浏览器使用和时间规划 Google Gemini CLI 免费安装配置指南:支持Gemini 2.5 Pro (2025最新) NixOS深度评测:一个六年Linux用户的初体验,为何惊艳的设计哲学仍让我望而却步 我的NS2使用体验记录,为什么因为马里奥派对空前盛会入坑 关于秦制的个人理解,为什么秦制在我看来是功过鲜明的必然 拜访一个人,在千年之后 Vercel/Netlify国内加速:EdgeOne免费CDN优选IP实战指南 C/C++程序员必看:JavaScript核心概念深度解析(动态类型、原型链、事件循环) C/C++程序员转向JavaScript:一份超详细的语法映射与避坑指南 从C++到JS:函数、this与闭包的核心差异与实践指南 VSCode配置JavaScript开发环境:Node.js安装与调试指南 C/C++程序员必看:JavaScript变量与作用域深度解析(从var到const) 博客迁移实战:从WordPress到Next.js的零成本高性能之路 《原则》读书笔记:如何将瑞·达利欧的智慧应用到日常 MATLAB入门教程:面向C++/OIer的数据可视化与科学计算指南 LaTeX公式与三线表教程:从入门到精通的排版指南 软路由远程访问提速:SMB压缩与50M上行优化实战 Hyprland 安装与配置超详细教程 (Arch Linux):含 Waybar 及一键脚本 Linux文件系统与磁盘分区:从入门到精通的实战指南 Guide to Installing a USB WiFi Adapter on OpenWrt (LuCI) 阿里云CentOS 9服务器从零到一:安全配置与宝塔面板安装指南
P12632 This Is Sparta!:数据会自己坍塌
间窗 (Vindo) · 2026-09-03 · via 静观小窗

最核心的思维主线

KK → 终局 → 零化 → 分层 → 下沉 → 坍塌 → 降维 → 快进

这道题最重要的不是最后的公式,而是发现:

原本有 10510^5 个数,但真正需要长期处理的数会越来越少。

原题链接:P12632 [ICPC 2025 NAC] This Is Sparta!

一、我最开始走的路线

看到:

K≤1018K\le 10^{18}

我立即想到:

KK → 不能模拟 → 推递推 → 找闭式

排序后,一轮操作满足:

b1=a1,bi=ai−bi−1.b_1=a_1,\qquad b_i=a_i-b_{i-1}.

继续展开,可以得到交错和,也可以发现奇数位、偶数位分别有序。

但是每轮结束后都要重新排序。

排序会打乱元素的位置,因此单轮递推无法直接扩展成 KK 轮闭式。

这条路最终断在:

递推 → 排序 → 断裂

二、真正重要的苗头:后期会有很多 00

我当时其实短暂想到过:

后面是不是会出现很多 00

但因为没有立刻得到证明,就把这个想法放掉了。

实际上,00 是一个不可逆状态:

0→0.0\rightarrow0.

因此:

零的数量单调不减\boxed{\text{零的数量单调不减}}

等价地:

正数的数量单调不增\boxed{\text{正数的数量单调不增}}

这说明问题的有效规模可能不断缩小。

此时最应该追问的不是:

怎样快速计算很多轮?

而是:

很多轮以后,还剩多少个数需要计算?

三、直接研究“变成 00”太难,就先研究“下降一层”

把正数按照二进制数量级分层:

[1,2),[2,4),[4,8),…[1,2),[2,4),[4,8),\ldots

考虑同一层中的两个相邻数:

ai,ai+1∈[2j,2j+1).a_i,a_{i+1}\in[2^j,2^{j+1}).

下一轮中,如果

bi<2j,b_i<2^j,

那么 bib_i 已经下降一层。

否则 bi≥2jb_i\ge 2^j,于是:

bi+1=ai+1−bi<2j+1−2j=2j.b_{i+1}=a_{i+1}-b_i<2^{j+1}-2^j=2^j.

那么 bi+1b_{i+1} 一定下降一层。

所以:

同层相邻的两个数,至少有一个会下沉\boxed{\text{同层相邻的两个数,至少有一个会下沉}}

也就是:

同层 → 相减 → 下沉

不断重复:

下沉 → 下沉 → 下沉 → 零化

所有数都不超过 101810^{18},二进制层数只有约 6060 层。

因此,大量元素会不断下沉,最终变成 00

这就是数据坍塌。

四、坍塌之后再快进

原问题看起来有:

N=105N=10^5

个状态。

但模拟足够多轮后,只会剩下至多三个正数。如果此时 KK 还没有耗尽,就可以转入常数维处理。

于是:

高维 → 坍塌 → 低维

只剩三个数:

a≤b≤ca\le b\le c

且顺序暂时不变时,经过 tt 轮:

[a,  b−ta,  c−tb+t(t+1)2a].\left[ a,\; b-ta,\; c-tb+\frac{t(t+1)}2a \right].

这时才使用闭式批量跳跃。

只剩两个数时:

[a,b]→[a,b−a],[a,b]\rightarrow[a,b-a],

就是欧几里得算法。

因此完整解法不是一开始就快进,而是:

先模拟坍塌,再低维快进。

这道题真正应该记住什么

不是记住“二进制分桶”。

而是记住这个触发:

超大轮数 + 不可逆变化 → 先看终局

发现死亡状态后:

死亡 → 活跃数

无法证明立刻死亡时:

死亡距离 → 分层

发现层级不断下降后:

分层 → 下沉 → 坍塌

最后才是:

坍塌 → 降维 → 快进

最终主线

KK → 终局 → 零化 → 分层 → 下沉 → 坍塌 → 降维 → 快进

再压缩一次:

终局 → 下沉 → 坍塌 → 快进

这道题不是在问:

怎样快速执行 101810^{18} 轮?

而是在问:

执行不了多少轮以后,原来的 10510^5 个状态还剩下几个?