记录一下踩过的各种坑~
编程语言:
-
C/C++
-
for循环
- 第三条: 不要贪图方便,写出 Q[i].id=i++ 这种代码,其实它是 Q[i+1].id=i, ++i,而不是 Q[i].id=i, ++i!
-
builtin
- __builtin_ctz(x)、__builtin_clz(x): 务必确保 x!=0 !由于行为未定义,可能会出各种奇奇怪怪的错误,比如
TLE
- __builtin_ctz(x)、__builtin_clz(x): 务必确保 x!=0 !由于行为未定义,可能会出各种奇奇怪怪的错误,比如
-
数据结构:
- 线性结构
- ?
- ?
-
树状结构
-
笛卡尔树
- 建树: 第一注意建树用的栈和我平常的习惯不同,这里是 ++top \text{++top} ++top 和 top − − \text{top}-- top−−;第二注意建完树后要记录 root \text{root} root,并把 NIL \text{NIL} NIL 的右指针改回来。
-
线段树
-
val \text{val} val 域: 线段树没有 val \text{val} val 域,因为线段树维护的是区间信息( FHQ Treap \text{FHQ Treap} FHQ Treap 则有)。
-
优先级: 懒标记优先级要特别注意,尤其是有区间赋值或类似操作时。
-
偏移量: ZKW \text{ZKW} ZKW 线段树要注意一开始必须处理偏移量,而普通线段树不用(可随便选择维护区间的端点)。
-
懒标记初始化: 懒标记应该在 build \text{build} build 的第一行和 l l l、 r r r 一起无条件初始化,不要放在 init_v \text{init\_v} init_v 宏里面! init_v \text{init\_v} init_v 只负责 init \text{init} init 叶节点存储域,而懒标记大家都要清空。
-
-
FHQ Treap
-
val \text{val} val 域: 这货有 val \text{val} val 域。
-
复制代码: 复制粘贴 merge \text{merge} merge 代码改成 split \text{split} split 的时候,注意要改引用类型。
-
不要动 NIL \text{NIL} NIL: 如果有改值操作,在成员函数里面一定要特判掉 NIL \text{NIL} NIL 结点,防止将其值修改了。比如如果对它进行区间赋值了,又维护着 min \text{min} min 域,那 NIL \text{NIL} NIL 的 min \text{min} min 就不再是 SINT_MIN \text{SINT\_MIN} SINT_MIN 了,那么对于那些只有一个儿子的结点,它 push_up \text{push\_up} push_up 的时候就可能会出问题。
-
max \text{max} max 域:注意 FHQ \text{FHQ} FHQ 维护 max \text{max} max 域时的操作和线段树不一样!线段树 FHQ \text{FHQ} FHQ 有 val \text{val} val 域所以它是 max = MAX(val, MAX(lc->max, rc->max)) \text{max = MAX(val, MAX(lc->max, rc->max))} max = MAX(val, MAX(lc->max, rc->max)),不要忘了 val \text{val} val !
-
-
树链剖分
- 维护边权: 维护边权对于维护点权有一处修改和两处不同:修改是要在 dfs1 \text{dfs1} dfs1 的时候给边更新一下儿子序号。两处不同是在操作的时候,对于链处理,要 改不跨链时的操作起点 和 添加对同点的特判;对于子树处理,不能像维护点权那样一次到位,要把区间拆成两部分,即剔除该子树根结点的父边。
-
算法:
-
动规
-
数位dp
-
- 树上
-
dfs序
- 数组大小: 如果是要用欧拉序(比如要对
dfs
\text{dfs}
dfs 序做
RMQ
\text{RMQ}
RMQ),那么记得开两倍结点数。
- 数组大小: 如果是要用欧拉序(比如要对
dfs
\text{dfs}
dfs 序做
RMQ
\text{RMQ}
RMQ),那么记得开两倍结点数。
-
-
图论
-
SPFA
-
队列数组大小: SPFA \text{SPFA} SPFA 非常玄学,每个点可能进队好几次,所以队列仅开 MV \text{MV} MV 是不够的。理论上最大应该要开到 MV 2 \text{MV}^2 MV2 但这容易炸内存… 所以要么写循环队列,要么老老实实用 std::queue \text{std::queue} std::queue 或者 deque \text{deque} deque。
-
玄学优化: SPFA \text{SPFA} SPFA 的优化也很玄学,一般来说就开个 SLF_SWAP \text{SLF\_SWAP} SLF_SWAP 就行,千万别开朴素的 SLF \text{SLF} SLF,玄学至极!另外 LLL \text{LLL} LLL 和 MCFX \text{MCFX} MCFX 一般都没什么用。
-
-
网络流
- 无向有向区别:虽然都有相反弧,但是对于有向图,相反弧是用来反悔的,所以反向弧初始容量是 0 0 0,每次正向弧选多少就给它增加多少的反悔空间。换句话说也就是说每一对相反弧的净流量必须是正向的!(反向弧再反悔也不能反悔到净流量反向)而无向图,反向图初始容量就和正弧相同,也就是说一对相反弧的净流量可以是双向的。
- Dinic \text{Dinic} Dinic: 注意判 in \text{in} in 优化和当前弧优化的顺序!如果都要写在 for \text{for} for 的第二部分,一定要先判 in \text{in} in。
-
- 分治
- ?
- 字符串
- ?
- ?
- 计几
- ?
- ?
- 数论 & 数学杂项
- ?
- ?
路还相当长…但还是要加油鸭