时间复杂度 Complexity

时间复杂度衡量算法的用时(加法、乘法这样基本操作的数量)随着数据规模的增长而增长的趋势。

最重要的时间复杂度衡量是渐进上界,也就是f(n)=O(g(n))f(n)=\mathcal{O}(g(n)),当且仅当 c,n0\exists c,n_0,使得 nn0,0f(n)cg(n)\forall n \ge n_0,0\le f(n)\le c\cdot g(n)

时间复杂度在算法比赛中很重要,因为对于很多问题,正确而巧妙的算法(所谓“正解”)能够在给定的计算时间给出结果。CSP的计算机时间限制一般为1秒, 在这种情况下,C++代码中的操作次数控制在10710^7 ~ 10810^8为最佳。 而如果没有找到对症下药的正解算法,则往往不能对所有测试例在计算时间限制内给出结果,只能得到部分分数。

资源
OI-Wiki算法复杂度时间复杂度和空间复杂度是衡量一个算法效率的重要标准。

一些简单的复杂度例子

常见算法的复杂度

以下是比赛中一些常用操作的复杂度:

题目给出的数据规模往往指明了算法的复杂度上限,很多题目都可以通过数据规模来猜测可能大致用什么类型的算法。这是每道题读题都要快速考虑的步骤。 下表列出常见的数据规模,和对应的算法复杂度上限:

nn时间复杂度上限
n10n \leq 10O(n!)\mathcal{O}(n!), O(n7)\mathcal{O}(n^7)
n20n \leq 20O(2n)\mathcal{O}(2^n), O(n5)\mathcal{O}(n^5)
n80n \leq 80O(n4)\mathcal{O}(n^4)
n400n \leq 400O(n3)\mathcal{O}(n^3),
n7500n \leq 7500O(n2)\mathcal{O}(n^2)
n7104n \leq 7 \cdot 10^4O(nn)\mathcal{O}(n\sqrt{n})
n5105n \leq 5 \cdot 10^5O(nlogn)\mathcal{O}(n \log{n})
n107n \leq 10^7O(n)\mathcal{O}(n)
n1018n \leq 10^{18}O(log2n)\mathcal{O}(\log^2 n), O(logn)\mathcal{O}(\log n), O(1)\mathcal{O}(1)