记录一些 sb 错误
\(\bigstar\) 代码不求写的快!!!写完一个函数看看会不会有边界等未考虑的问题等
- 离散化的最小值 \(val_0\) 应该赋值为不可能达到的值( \(val_0=-\infty\) )
- 函数传参数从右到左,在
f(rd(),rd())
后会反过来。 - 连续的
if
中记得加上else
。因为在if
中可能会改变下一个if
的判断条件(如某一次洛谷月赛) - 数组不要开小啦!好多次了,看到一个 \(n\) 的范围就将 \(m\) 的范围也开成 \(n\) 的范围。20220805 模拟赛 T2
- 可能取模的题目中实时取模!(又犯了一次,如 NOIP2021 T2)
- 手写
bitset
时移位操作为(1llu<<((1llu*i-1llu)%64llu))
,不要忘了llu
!!! - 输入尽量不要用
%c
,可以用%s
代替。 - 拓扑排序时,要将整张图中入度为 \(0\) 的点全部加入,以保证能遍历整张图(即使我们不需要遍历其中一些点)(如 NOIP 函数调用)
- 当要求给浮点数赋值为 \(\infty\) 时,不要用
0x3f3f3f3f
,要用2000000000
之类。 - 1 不是素数!!!
- 一些需要懒惰标记的题目中用
laztag,lazval
分别来表示是否有标记、标记信息,不要只使用一个lazval
同时维护是否有标记。 set
和sort
的<
一定要是有严格的偏序关系,也就是说必须满足传递性,必须不满足自反性,也就是说不能既a<b
又b<a
。- 多测清空时,记住如果需要访问下标为
n+1
的地方,记得把第n+1
位也清空(如某一场 CF 比赛) - 树剖路径修改时关注信息在点上还是在边上,这决定了是否要在
lca
处再次处理。 - 输入时不要在数组中放
rd()
函数!可能会出一堆 Ub,如mp[rd()][rd()]=rd();
是错误的! - 合并两个点的时候记得判读他们是否已经处在同一个集合中。
- 没有线段树等奇怪操作时(
define
是暴力展开,会让复杂度假掉)可以将 \(\max\) 和 \(\min\) 用define
减小常数。 - 珂朵莉树、FHQ 等
split
一个区间时要先分裂右区间再分裂左区间,因为rank
在分裂后会对后面的数产生影响。 - 内外层变量重名了。(好像可以用
-Wshadow
报Warning
)。 - 可撤销并查集的秩是深度,启发式合并需要的是大小。
- 有的时候做题需要特判一些取模情况,如在 \(\bmod p\) 时输出 \(2\),不能直接
puts("2")
,要printf("%d\n",2%p)
。 - 三个 \(<998244353\) 的数相加相减会爆
int
,如ans=(ans-sum+mod)%mod
可能会导致爆int
。 - 模数看错,如
1e9+7
看成998244353
。 - 在倍增跳
lca
时判断是否会跳到 \(0\)!(如 P7834 Peaks 加强版) - 数组长度是 \(n\) 还是 \(m\)??这是问题
- 当 \(x\) 超过
int
时,调用__builtin_popcount(x)
会出问题,需要使用__builtin_popcountll(x)
。 - 对于字符串长度,如果长度为 \(3\) 不能只开到 \(3\),至少开到 \(4\) 或 \(5\),首先是下标 \(0\),其次字符串末尾会自动天上
\0
导致空间 \(+1\)。 - 当在比赛中想去测试点分治的时候,不要将各个测试点的代码写在一起!(由于为了
subtask3
把subtask1
丢了)update on ZJOI Day 1 T2 - 记住期望转移的时候,将期望转移过来乘上转移概率,见新的贡献转移过来乘上达到上个状态概率和转移概率。
- 最短路如果边权要赋值为 \(\infty\),要注意它会不会在累加的时候爆
long long
!!!一个较好的建议是 \(10^{12},10^{15}\) 之类的(P7624 [AHOI2021初中组] 地铁 的两个小时!!!) - 主席树中①只能在最新版本节点修改②不能直接在这个节点上修改自己,要另存一个节点 CF464E
- 动态开点数据结构若要垃圾回收一定要清空 \(ls, rs\) 等 CF702F
- 若答案存在有 \(laz\) 标记的节点上,在最后要将所有 \(laz\) 下传 CF702F
- 类似点分治合并子树的时候,要先查询,后将子树添加到根的答案中,不要一遍查询一边添加!!!可能会让新加入的点和自己形成答案 CF1709E
- 字符还是字符串输入以后都用
scanf("%s",ch)
,不要%c
啦啦啦!!!P1503 - 当我们访问
n-x+1
的时候注意可能访问到下标 \(n+1\)!!!要将 \(n+1\) 也赋值!!P4456 - 线性预处理阶乘逆元的时候,一定循环到 \(mod-1\)!!有点时候会 \(n\ge mod\),这样倒着预处理会导致前面的逆元被赋为 \(0\)!!P4456
- 当在有重边、自环的图中找出一棵生成树的时候(特别是当我们需要记录横叉边、返租边),在 dfs 中不要用
ver[i]!=fa
!!很有可能将需要的重边忽略掉!!应该对每条边记录是否访问过。P3733 long long
不要忘开/fn 两场 CF 的 FST- 乘 \(1ll\) 的时候不要乘成 \(1.0\)!!!CF575A
- 定义函数的时候不要用
auto
!!这样会 CE - 在线段树分治中,结束 id 为 \(i-1\);加边时需要判断 \(pl\le pr\);在线段树端点也需要进行修改操作(即使有询问)。CF938G
- 并查集一定要判
if(x==y) return
!!不然可能会算重、TLE 等各种错误!!CF576E - 数组要多开大 \(3,4\) 位左右,不然也会出 Ub。CF576E
- 注意扩展域并查集、记录操作(可撤销)的数组、栈等都要开两倍空间!!!CF576E
- 线段树中 laztag 的极值一定不能取到!!比如
infll
与inf
要区分清楚 CF1163F
为了防止线段树标记下方顺序有误,以后不妨这么写:(以 GSS2 为例)
struct TREE
{
// All=pushed+unpushed
ll maxAll,All,maxUnpused,Unpushed
TREE(int _maxAll=0,int _All=0,int _maxUnpushed=0,int _Unpushed=0):
maxAll(_maxAll),All(_All),
maxUnpushed(_maxUnpushed),Unpushed(_Unpushed){}
inline void Push(ll New,ll maxNew)
{
maxAll=max(maxAll,All+maxNew);
All+=New;
maxUnpushed=max(maxUnpushed,maxNew);
Unpushed+=New;
}
}tree[Maxn<<2];