注意事项
在这里列举一些代码中经常出错的问题以及一些代码技巧。
-
\(head\) 数组一定要初始化为 \(-1\)(如果死循环很有可能是这里的问题)
-
建图要考虑建双向边还是单向边。
-
有向图 \(Tarjan\) 的时候不要写成
if(u == dfn[u])
-
存图的数组要多开几倍。
-
函数名首字母尽量用大写,以防重名。
-
用 \(double\) 计算时一定要考虑精度问题,特别是二分的时候。
-
除 \(void\) 函数以外的函数一定要有返回值,特别是 \(bool\) 类型函数,不然会自动返回 \(0\)。检查返回值是否正确。
-
STL 里的数据结构时间复杂度要带一个 \(\log\) 或者带一个常数,谨慎使用。
-
模 \(1e9 + 7\) 的时候不要写成了模 \(1e9+10\)。
-
直接枚举子集可能会 \(TLE\),可以这样优化
for(int j = i & (i - 1);j;j = (j - 1) & i)
-
不要开 \(1e6\) 个 \(deque\) 然后喜获 \(MLE\)。
-
注意 \(memset\) 的用法,可能会 \(TLE\)。而且注意应该手动赋值还是用 \(memset\)。
-
用 \(sqrt\) 的时候,要注意精度误差之类的问题。
-
分块的时候注意是 \(i\) 还是 \(l\),是 \(i\) 还是 \(pos_{i}\),需不需要加/减懒标记。
-
分块的时候要分清自己要求的是块内的还是整个序列上的,需不需要减 \(lid_{i}\)。
-
写分块或者线段树的时候记得写 \(init\) 和 \(build\)。
-
线段树注意 \(pushup\) 和 \(pushdown\) 的位置,\(pushup\) 在 \(build\) 和 \(add\) 最后,而 \(pushdown\) 在 \(add\) 和 \(query\) 的中间。
-
注意计数题要不要取模,在什么地方取模,取模有没有取干净。
-
注意指针移动应该是 \(pos++\) 还是 \(++pos\)。
-
树剖查询和修改往上跳的时候是 \(u=fa_{top_{u}}\) 而不是 \(u = top_{u}\)。
-
线段树修改懒标记的时候应该 \(tree_{ls}.add+=tree_{id}.add\) 而不是 \(tree_{ls}.add=tree_{id}.add\)。
-
当线段树既要区间加又要区间推平的时候注意懒标记的处理。
-
\(double\) 类型返回值的函数不要写成 \(int\) 了。
-
注意做除法的时候要不要保留小数,有没有保留小数。
-
线段树记得开四倍空间(
除非是查理线段树)。 -
模拟退火用 \(exp\) 算接受劣解的概率的时候注意有没有算反,有没有 \(delta = 0\) 的情况.
-
模拟退火或者其它时候生成 \(1-n\) 中的随机数是
rand() % n + 1
而不是rand() % n
。 -
不要将 \(==\) 写成 \(=\),否则会赋值。
-
注意循环层数很多时要分清楚下标到底是谁,\(i\) 还是 \(j\) 还是 \(k\),不要弄混了。
-
按照双关键字排序的 \(cmp\) 函数是
y < t.y
而不是x < t.y
。