解题报告——论对“数据分治”的新理解

解题报告——论对“数据分治”的新理解

所谓数据分治,就是对于一道题我们有多种算法,如果一个一个地运用这几种算法,每个都不能通过这道题,但是每种算法都有其最适合的数据范围,我们根据不同的数据运用不同的算法,就可以通过这道题。

一般的数据分治都是根据输入数据的规模分治的,但是有些数据分治是“思维上的”数据分治,跟输入数据完全无关,这样的数据分治,本身就可以是为一种算法,所以这样的题一般都是思维好题。

这道题告诉我们就算是 \(\text{OI}\) 的思维也可以运用到 \(\text{ACM}\) 赛制中。

先考虑一个最朴素的暴力,如果我们把 \(b\)\(1\)\(n\) 枚举,时间复杂度是 \(n\lg n\) 的,无法通过这道题。

再从反向思维考虑,我们枚举 \(n\) 最后变成了什么样,就是 \(n\)\(b\) 进制下的 \(01\) 串长什么样,然后二分查找这个 \(b\) 是否存在,时间复杂度也是 \(n\log n\) 的。

现在想,如果我们已经确定了一个 \(b\),那么 \(b\) 越大,上面那个算法的复杂度就越大,但是下面这个算法的 \(01\) 串就越短。

从这里开始我们就可以对 \(b\) 数据分治了。我设置的边界是 \(b\)\(1\) 枚举到 \(3.5\times 10^4\)\(01\) 串从 \(0001\) 枚举到 \(1111\)

那么这道题目已经不重要了。我们剖析一下数据分治的本质。

回到一开头的定义来——通过这道题我们可以看到,有一些算法的复杂度随着 \(n\) 的增大而增大,但还有另外一些算法的复杂度随着 \(n\) 的增大而减小。如果我们把这些算法时间复杂度随 \(n\) 变化的关系画到一个函数图像上,那么其就像这样:

那么我们数据分治要干的是什么?对于每个 \(n\) 取到复杂度的最小值。那不就是凸包吗?

这启示我们:当我们想要数据分治但情况太复杂的时候,我们甚至可以搞个凸包来帮我们判断哪个数据用哪个算法,甚至还可以把这个凸包加到代码中。

posted @ 2025-01-14 21:05  KarmaticEnding  阅读(16)  评论(0)    收藏  举报