\(f(n)=O(g(n))\) 代表存在常数 \(c,n_0\) 使得 \(\forall n>n_0,f(n)\le c*g(n)\) 。
\(f(n)=\Omega(g(n))\) 代表存在常数 \(c,n_0\) 使得 \(\forall n>n_0,f(n)\geq c*g(n)\) 。
\(f(n)=\Theta(g(n))\) 代表存在常数 \(c_1,c_2,n_0\) 使得 \(\forall n>n_0,c_1g(n)\le f(n)\le c_2g(n)\) 。
\(f(n)=o(g(n))\) 代表 \(\lim\limits_{n\rightarrow +\infty} \frac{f(n)}{g(n)}=0\) 。
\(f(n)=\omega(g(n))\) 代表 \(\lim\limits_{n\rightarrow +\infty}\frac{f(n)}{g(n)}=+\infty\) 。
主定理:
形如 \(T(n)=aT(\frac{n}{b})+f(n)\) ,\(T(1)=1\) 。
\(f(n)>n^{\log_ba}\) 则 \(T(n)=\Theta(f(n))\) 。
\(f(n)=n^{\log_ba}\) 则 \(T(n)=\Theta(n^{log_ba}\log n)\) 。
\(f(n)<n^{\log_ba}\) 则 \(T(n)=\Theta(n^{\log_ba})\) 。
分治。
一个题目:有 \(n\) 个物品分为 \(A,B\) 两种满足 \(A\) 物品多于 \(B\) 物品 ,你不知道物品的种类。你需要通过交互找出来一个 \(A\) 物品。只能进行 \(O(n)\) 次查询,每次可以丢给交互库两个不同的物品,交互库会给你返回 \(0\) 或 \(1\) 满足:如果两个物品都是 A ,那只会返回 \(1\) ;如果两个物品 1A1B 只会返回 \(0\) ;否则返回 01 皆有可能。
做法:
如果 \(n\) 是偶数则把物品分为两两一组,对每一组分别查询,若返回 1 则丢掉其中一个;否则都丢掉。不难发现丢完了之后还是满足 A 多于 B ,递归做下去就好了。
如果 \(n\) 是奇数:取出任意一个物品,将它和其他每个物品分别比较一次。如果返回 \(1\) 的次数 \(\geq \frac{n-1}{2}\) 则为 A;否则为 B。如果是 A 就直接输出了,否则把 B 给丢掉。
更好的做法:其实 \(n\) 是奇数的时候不需要通过 \(n-1\) 次判断一个物品的好坏。还是两两分组,做偶数时干的事情。设此时保留的物品个数为 \(C\) ,如果 \(C\) 是偶数就直接把这个多出的保留;否则将其丢掉。
更 ez 的做法:随机一个物品做 \(n-1\) 次比较判断 AB,期望 \(2\) 次就能随到 A 物品。
kth_element 随机做法:
随机一个数 \(w\) ,计算序列中 \(<w\) 的个数 \(s_1\) 和 \(>w\) 的个数 \(s_2\) 。如果 \(s_1<k\le n-s_2\) 那直接得到答案为 \(w\) 了;否则,如果 \(k\le s_1\) 就能只保留前 \(s_1\) 个数,递归做下去;否则只保留后 \(s_2\) 个数,递归做下去。
考虑每次至多保留 \(\max(s_1,s_2)\) 个数。由于 \(w\) 是随的所以这个期望是 \(\frac{2}{3}n\) 。\(T(n)=T(\frac{2n}{3})+\Theta(n)\) 。
确定性做法:
考虑将物品分为 \(5\) 个一组,求出每一组的中位数,再把找出的 \(\frac{n}{5}\) 个数的中位数递归的求出来,设之为 \(w\) ,对 \(w\) 做上面的事情,递归的做下去。由于 \(s_1,s_2\le \frac{7}{10}n\) ,我们有 \(T(n)=T(\frac{1}{5}n)+T(\frac{7}{10}n)+\Theta(n)\) ,这个解出来是 \(\Theta(n)\) 的。
卷积:
对于 \(F(x)\) 设 \(F_0(x)\) 是 \(F\) 保留偶数项系数后的多项式,\(F_1(x)\) 是保留奇数项,我们有 \(F(x)=F_0(x)+xF_1(x)\) 。
发现 \(F(W_{2n}^x)=F_0(W_{n}^x)+W_{2n}^xF_1(W_{n}^x)\) 。
递归计算即可。
大整数乘法:设 \(A=2^{m}a+b,B=2^mc+d\) ,可以得到 \(AB=2^{2m}ac+2^m(ad+bc)+bd\) 。
考虑 \(ad+bc=(a+b)(c+d)-ac-bd\) 。递归计算 \(ac,bd,(a+b)(c+d)\) 即可。
复杂度 \(T(n)=3T(\frac{n}{2})+O(n)\) ,即 \(O(n^{log_23})\) 。(Karatsuba)
当然可以更优。最新的结果已经做到 \(O(n\log n)\) 了。
矩阵乘法:类似的,对矩阵分块,8 次转 7 次,有 \(T(n)=7T(\frac{n}{2})+O(n^2)\) 。
\(O(n^{\log_27})\) 。(Strassen)
当然可以更优。最新结果 \(w\) 约为 \(2.371\) 。