杂项\cry指的不是不好归类的算法,而是一些简单的需要注意的事项。

这篇文章很多该写的地方并没有写完甚至没有开写。

常读常新,提醒自己哪些错误经常犯,有意识地矫正。

二分中的细节

左闭右闭:mid = l + r + 1 >> 1,l = mid + 1,r = mid

左闭右开:mid = l + r >> 1,l = mid,r = mid - 1

l = mid - 1找区间中满足条件的最大索引;r = mid + 1找区间中满足条件的最小索引

如果数组是a[] = [1, 3, 3, 3, 5],那么

lower_bound(a, a+5, 3) = a+1, upper_bound(a, a+5, 3) = a+4

lower_bound(a, a+5, 4) = a+4, upper_bound(a, a+5, 4) = a+4

lower_bound(a, a+5, 5) = a+4, upper_bound(a, a+5, 5) = a+5

lower_bound(a, a+5, 5) = a+5, upper_bound(a, a+5, 5) = a+5

概括起来,就是lower_bound返回大于等于x的最小地址,如寻找不到这样的下标,则返回尾地址;至于upper_bound,则把上文的大于等于改为大于。

常见

常见错误

忘记特判。

未认真读题/关注clarification或notes。

未初始化全局变量(特例:树状数组在清空后无需初始化)。

变量名重复。

关于溢出(数值)

取模不及时常会导致数字溢出模数,或者忘加LL可能导致中间结果溢出int。

为防止溢出,最好处处取模,处处用LL(包括所有常数),这是一个ctrl+F/H的事,却能节省不少的没有必要的心思。

需要指出的是,处处取模只针对大多数情况,如果数字在指数上(如Polya定理的题目),则万不可取模。某些毒瘤出题人把模数取小后会这样坑人。

有些题目的中间结果可能溢出double,而又只涉及乘法运算,这种时候可以考虑取对数。

关于溢出(内存)

把数组开到maxn不一定总是能防止runtime error,具体把数组开到多大,需要留个心眼。

把数组开到多大才能足够安全并且不会MLE呢?可以采用简单的费米估算:1e6大小的int数组所用空间约为4MB(另,1Mib≈1MB)。

FTT/NTT中数组必开到二的幂次+eps。

无向图连边时数组需开到maxn<<1。

简单的结论

1.求$x \cdot (x-1) \geq y$的最小解,无需二分。只要检查$x = \lfloor \sqrt y \rfloor$是否满足即可。如不满足,则x++。

效率

1.ctrl+H可快速替换int为LL,%d为%lld,1为1LL。

2.ctrl+F在修改代码中的某类对象时可以指出这类对象都在哪出现过。

3.namespace中存板子可以降低程序的耦合度,提高程序员的效率。

4.python极其适合用来生成随机测试数据,图论题的数据除外。

带东西

算法书要自己读过理解过,对里面的内容有结构性的认识带过来才派得上用场。当然现场学算法也无不可

语法书在不让使用通讯工具的场合是必要的,比如JAVA的语法书,PYTHON的语法书。C中一些不常用库的语法也要记记,比如time.h等(带小册子也行打印稿也行)

数学书:数分、线代、概统、离散、数论、图论、抽代

字典要带也带吧,虽然感觉并不能派上用场。(这些出题人怎么都这么骚,经常出阅读理解题,还有unidirectional可还行)