写在前面#
下面的内容中每一个挂分小技巧:
第一行是指出了错误,第二行及以后说出了正确做法(可能没有),
如有不是的会特别指出,请注意。
常见的挂分小技巧#
取模中的挂分小技巧#
- 模数取错。
- 不随时取模。
注意取模,看好两个数相乘的结果是否会爆出你所定义的类型。
当然也不是取模越多越好,因为取模本身比较慢,所以应该在合适的地方取模。 - (特别指出,此处为正确做法)在取模时注意负数的取模。
本质为手误的挂分小技巧#
- inin 和 outout 文件写错,正确写法(根据题目而定):
freopen("a.in", "r", stdin);
freopen("a.out" ,"w", stdout);
- 莫名其妙在代码里多加了几个符号。
- 奇奇怪怪的手误,比如:变量写错,ii 和 jj 写反,f[y][i]f[y][i] 写成 f[y][y]f[y][y],s=read(),t=read()s=read(),t=read() 写成 s=read(),s=read()s=read(),s=read()。
规范写法, 能写 k>0 就不写 k, 循环变量要多变,不要只写 ijk, 冗余信息可以减少出错。
本质为脑抽的挂分小技巧#
- 不写读入。
- 数组开小。
- 快读把字符写成整形。
- 自作聪明,不看题目要求。
认真读题啊,先把题目多读几遍圈画出重要信息再做
更小的数组,更多的挂分。 - 该开 long longlong long 的题没开 long longlong long。
- 多测不清空,爆零两行泪。
多组数据记得清空,注意清空要完全。 - 炸空间,或者空间开小,有的题空间开小不一定会 RERE,还有可能会 WAWA。
- 不好好看看数据范围。
数据范围十分重要!直接决定了你的分数!
231231 比 0x3f3f3f3f0x3f3f3f3f 大! - 在有返回值的函数中不加 returnreturn。
- 不给局部变量赋初值。
记得局部变量变量赋初值,否则会死的很惨,就像下面这样,一个代码四个答案。 
- 自以为开了 longlong 但在一处微小的地方没开 longlong。
认真检查,杜绝发生。 - 写有
else 的 if 语句时忘记写 else。
图论中的挂分小技巧#
- 带权边建成无权边。
- 双向边建成两条一样的单向边。
不要求快,要求准,用好自己的手和眼。
倍增求LCA#
- 倍增lca 把根节点的深度设成 0
不是很常见,这样无法和跳到 NULL 区分。
最短路#
- 单向边建成双向边
单向边,单向边! - 有向图建成无向图
有向图,有向图!
- 读入一棵树的时候读入了 nn 条边。
一棵树是一张有 nn 个点 n−1n−1 条边的连通图。
网络流#
- 建边从奇数开始建。
建边要从偶数边开始建,这样 i^1i^1 才能找到 ii 的反向边。 - 建了编号为 00 的边但是没初始化 headhead 数组为负值。
如果要建编号为 00 的边 一定记得初始化 headhead 数组为 −1−1 。 - 不判断容量为 00 的边是否为起点 SS。
输出方案时容量为 00 的边不一定是用过的边,还有可能是从起点连过来的边的反向边,所以输出方案时要判断这种情况。
矩阵中的挂分小技巧#
数据结构中的挂分小技巧#
不知道放到哪儿#
- 一系列需要动态开点的数据结构(主席树,SAM)没有继承之前状态的信息。
单调栈#
主席树#
- 吝啬空间,空间开小。
一定不能吝啬空间,开 3030 倍左右? - 在主席树中,
if (k <= tmp) query(t[x].l, t[y].l, t[lca].l, t[fa_lca].l, l, mid, k); 中的 k<=tmp 写成 k>=tmp。 - 在 buildbuild 函数中,忘记加 nownow,答案没错,但是程序运行十分缓慢。
void build(int &now, int l, int r) {
build(t[now].l, l, mid), build(t[now].r, mid + 1, r);
线段树#
- query,updatequery,update 函数中的 l,rl,r 写成 l,midl,mid 和 mid+1,rmid+1,r
如果是用结构体记录了每个区间的左右端点,那么函数中的 l,rl,r 指的是要查询或要修改的区间,这个区间的端点应该是不变的。 - 吝啬空间,空间开小
至少开 44 倍空间,最好不止 44 倍,特别是当 nn 达到 5e55e5 级别时,要千万注意。 - 权值线段树维护的值域 出现了负数,没有添加偏移量。
树链剖分#
- 混淆变量名、函数名
因为这个WAWA过(比如在dfs1dfs1里调用了dfs2dfs2……) - 树链剖分 dfs2 中 top[u]=utop[u]=u 实现了暴跳
- 跳到链顶。
在树剖过程中跳的时候是跳到链顶的父亲节点那里,而不是跳到链顶。 if(dep[x] < dep[y]) swap(x, y) 写反导致TLE- 写树剖时线段树部分中建树用
sum[x] = a[x]
这个就不用多说了吧…… - 主函数里没有写两个 dfs,只写了线段树的建树
你可能建了一棵权值全部为 0 的线段树。 - 树剖区间取值时把原线段树 query 函数的 l,r 和 L,R 写反
理解好每个变量的意义,不要硬记。
平衡树#
- FHQFHQ 合并的两棵树 不是 SplitSplit 分裂获得的两棵树。
LCT#
- LCTLCT 旋转时最后更新祖父信息。
虽然 splaysplay 可以这么写,但 LCTLCT 中由于之前的操作改变了结构,写法不当会导致祖父的信息出错。
STL中的挂分小技巧#
- (特别指出,此处为正确做法)类似 堆 和 vector 的 STL 在使用的时候, 要注意是否为空
DP中的挂分小技巧#
状压DP中的挂分小技巧#
- 状压DP的时候写错运算符
(fl & l) → (fl && l)
背包DP#
字符串中的挂分小技巧#
(和字符串有那么一丢丢关系的的就都放这了。
- 没有注意 charchar 类型的上限是 127127,写了
'z'+6 导致爆掉。
trie#
- 用 trietrie 处理二进制问题时,存储从高位到低位存 和 查询却按照低位到高位查。
数学中的挂分小技巧#
(和数学有点关系的就这儿了。
- 质因数分解漏掉
- exBSGSexBSGS 转化后指数可能为负数。
- 一个奇怪的边界问题。
对于 x∈Zx∈Z:
x≤a+b2⟺x≤⌊a+b2⌋x≤a+b2⟺x≤⌊a+b2⌋
x>a+b2⟺x≥⌊a+b2⌋+1x>a+b2⟺x≥⌊a+b2⌋+1
应用到C++特性的挂分小技巧#
- 声明数组时赋初值。
注意C++的特性:若在声明数组时为其赋初值,则会将整个数组遍历一边来赋值。 即使这样写: a[1e7] = {1} , 它仍然会遍历数组,并将 1~1e7-1 赋为0。 造成时间爆炸式浪费,以致编译超时,还会造成MLE。
很淦的挂分小技巧#
- 考 NOIPNOIP 的时候踢电源线。
这个小技巧实在是太狠毒了,不仅会让你挂分,还会让别人挂分,真是干得漂亮太恶毒了。 - 考试闹情绪。
- 删库。
- 在freopen 前边写读入。
- 激情码码码正确率高达 100% 然而忘了 prework(预处理)。
- 在主函数里调用
return main();。
高精度中的挂分小技巧#
- 写高精高精数组开得太大
写高精的时候,封装经常会用到 memset,高精数组开太大会导致memset时长加n倍,一定要估计好题目最大数的位数然后决定这个数组的大小
可能会导致挂分的小技巧#
- 使用 cmath 中自带的 max、min 函数
可能会比自定义函数慢