算法竞赛中根据数据规模猜测算法

C++ 竞赛中时间复杂度与数据规模的关系

核心经验法则

1 秒大约能执行 10⁸ 次基本运算(C++,O2 优化下)

这是所有判断的基础。竞赛中常见时限为 1s 或 2s


一、数据规模 → 可接受的最高复杂度

数据规模 nnn 可接受的复杂度 典型算法举例
n≤10n \leq 10n≤10 O(n!)O(n!)O(n!), O(2n⋅n)O(2^n \cdot n)O(2n⋅n) 全排列、状态压缩 DP
n≤20n \leq 20n≤20 O(2n)O(2^n)O(2n) 状压 DP、折半搜索
n≤30n \leq 30n≤30 O(2n)O(2^n)O(2n) 勉强 / O(n⋅2n/2)O(n \cdot 2^{n/2})O(n⋅2n/2) 折半枚举
n≤50n \leq 50n≤50 O(n4)O(n^4)O(n4) 区间 DP
n≤200n \leq 200n≤200 O(n3)O(n^3)O(n3) Floyd、普通 DP
n≤1000n \leq 1000n≤1000 O(n2log⁡n)O(n^2 \log n)O(n2logn) 二维 DP + 排序
n≤104n \leq 10^4n≤104 O(n2)O(n^2)O(n2) 冒泡排序、朴素 DP
n≤105n \leq 10^5n≤105 O(nlog⁡n)O(n \log n)O(nlogn) 排序、线段树、树剖
n≤106n \leq 10^6n≤106 O(n)O(n)O(n) 或 O(nlog⁡n)O(n \log n)O(nlogn) 勉强 线性扫描、前缀和
n≤107n \leq 10^7n≤107 O(n)O(n)O(n)(要写快) 筛法、桶排序
n≤108n \leq 10^8n≤108 O(n)O(n)O(n) 极限 一次性线性扫描
n≥109n \geq 10^9n≥109 O(n)O(\sqrt{n})O(n ), O(log⁡n)O(\log n)O(logn), O(1)O(1)O(1) 数论分块、二分、数学公式

二、快速心算公式

所需时间≈运算次数108 秒\text{所需时间} \approx \frac{\text{运算次数}}{10^8} \text{ 秒}所需时间≈108运算次数 秒

举例:

  • n=105n = 10^5n=105,O(n2)O(n^2)O(n2) → 101010^{10}1010 次运算 → 100 秒,超时
  • n=105n = 10^5n=105,O(nlog⁡n)O(n \log n)O(nlogn) → 105×17≈1.7×10610^5 \times 17 \approx 1.7 \times 10^6105×17≈1.7×106 → 0.017 秒,安全
  • n=106n = 10^6n=106,O(n)O(n)O(n) → 10610^6106 次 → 0.01 秒,安全
  • n=109n = 10^9n=109,O(n)O(\sqrt{n})O(n ) → 3×1043 \times 10^43×104 次 → 极快

三、常见复杂度的运算次数速查

以 n=105n = 10^5n=105 为例:

复杂度 运算次数 1s 内能否通过
O(log⁡n)O(\log n)O(logn) ∼17\sim 17∼17 轻松
O(n)O(\sqrt{n})O(n ) ∼316\sim 316∼316 轻松
O(n)O(n)O(n) 10510^5105 轻松
O(nlog⁡n)O(n \log n)O(nlogn) ∼1.7×106\sim 1.7 \times 10^6∼1.7×106 轻松
O(nn)O(n \sqrt{n})O(nn ) ∼3×107\sim 3 \times 10^7∼3×107 勉强
O(n2)O(n^2)O(n2) 101010^{10}1010 超时
O(n3)O(n^3)O(n3) 101510^{15}1015 严重超时

四、实战判断流程

复制代码
拿到题目
  │
  ▼
看数据范围 n
  │
  ├─ n ≤ 20     → 想指数级(搜索/状压)
  ├─ n ≤ 500    → 想 O(n³)(Floyd/区间DP)
  ├─ n ≤ 10⁴    → 想 O(n²)(朴素DP)
  ├─ n ≤ 10⁵    → 想 O(n log n)(排序/线段树/二分)
  ├─ n ≤ 10⁶    → 想 O(n)(贪心/双指针/单调栈)
  └─ n ≥ 10⁸    → 想 O(log n) 或 O(1)(数学/二分)

五、容易踩的坑

  1. 多组数据 :题目说 TTT 组询问,总复杂度要乘以 TTT。比如 T=105T = 10^5T=105,每组只能做 O(log⁡n)O(\log n)O(logn) 或 O(1)O(1)O(1)。

  2. 隐含的常数 :同样是 O(nlog⁡n)O(n \log n)O(nlogn),线段树常数比 sort 大好几倍,要注意。

  3. STL 的隐藏复杂度map 是 O(log⁡n)O(\log n)O(logn) 但常数大,unordered_map 均摊 O(1)O(1)O(1) 但有最坏 O(n)O(n)O(n) 的风险。

  4. 内存限制 :n=107n = 10^7n=107 的 int 数组约 40MB,n=108n = 10^8n=108 约 400MB,可能 MLE。


六、记忆口诀

十的八次方是一秒,对数永远不用急,平方过万要小心,指数二十是上限。

希望这个总结对你有帮助,比赛时拿到题先看 nnn 的范围,就能快速锁定该用什么复杂度的算法了。

相关推荐
灵感__idea12 分钟前
Hello 算法:贪心的世界
前端·javascript·算法
澈2071 小时前
深入浅出C++滑动窗口算法:原理、实现与实战应用详解
数据结构·c++·算法
A.A呐1 小时前
【C++第二十九章】IO流
开发语言·c++
ambition202422 小时前
从暴力搜索到理论最优:一道任务调度问题的完整算法演进历程
c语言·数据结构·c++·算法·贪心算法·深度优先
cmpxr_2 小时前
【C】原码和补码以及环形坐标取模算法
c语言·开发语言·算法
qiqsevenqiqiqiqi2 小时前
前缀和差分
算法·图论
代码旅人ing2 小时前
链表算法刷题指南
数据结构·算法·链表
kebeiovo2 小时前
atomic原子操作实现无锁队列
服务器·c++
Yungoal2 小时前
常见 时间复杂度计算
c++·算法
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 48. 旋转图像 | C++ 矩阵变换题解
c++·leetcode·矩阵