警钟敲烂

· · 个人记录

打算某天整理一下,目前一堆乱的。

长期置顶警钟:Um_nik 的建议

(本文 CF 原稿:here)

反复地、认真地、仔细地、一个字符一个字符地检查你纸上的式子是否和代码里的式子相同。

直线方程斜率是 tan(\theta) (zkq 给的数学题)

给 long long 类型赋值 2^k 时一定要写 LL t = 1ll << k !!!
因为LL t = 1 << k 这一句中,如果 k \ge 32, 那么 t 将获得不到正确结果!!(同余经典题 C Looooops)

数学题做一步模一下,不管是加法还是乘法。(P3049)

分讨注意正负性,注意取 max/min 每次都要设定初值,不然有些和原值(0)比会炸(CSP-S2 2022 T2)。

看清楚每个数组在哪个数组上面做离散化。(P1496)

看清楚树状数组的下标上限是多少,modify 时注意加到哪里停止,分清是 a_i 还是 n, 还是别的。(P1637)

关于状压的,不说了,直接上代码片段:

1 << j.(wzoi 题目)

形参和实参看清楚类型,别形参 int 实参 long long. (P4127)

能卡过的方法想到了就卡一卡,指不准常数小。(CF1878E)

multiset 是可重集,每次 insert 后不会少元素的,每个元素都是独立的,和 set 的最大不同就在这里。(CF1913C)

注意次短路的写法:更新最短路 -> 无法更新最短路,更新次短路。因为如果没有判断,这个节点的次短路就会同时更新成与最短路相等的值。(P2865).

最短路注意判断条件,不然会出事!!!

举个例子:

if(w[i] > mid && dist[j] > dist[t] + 1)
{
    q.push_back(j);
    dist[j] = dist[t] + 1;
}
else if(w[i] <= mid && dist[j] > dist[t])
{
    q.push_front(j), dist[j] = dist[t];
}

在这个时候,如果把 else 语句中 w[i] <= mid 去掉的话,那么 w[i] > mid 的情况会进入下面的分支导致 WA,所以一定要把所有条件写全!!! (P1948)

写最短路,注意进行到某个状态时,如果要增加 dist,最好把特判全部扔到外面,不要扔到循环里面。

因为花费增加时放到了循环里面,导致花费多次增加,肯定就 WA 了。(P4009)

看清楚最短路求 最大值还是最小值!!!(P1073)

最短路计数,别建 0 权边,否则会炸。可以学习本题方法。还有,用 printf 输出,注意数据类型!!!但凡是非大量重复输出的,都用 cout, 别在 printf 上用 %d 输出 long long 似半天!!!(P1606)

维护线段树的时候,能写单点,尽量写单点。(P2590)

三角形面积给我乘 1/2,切记每次重算几遍。

写 Lucas 定理(等等其他东西)的时候,注意 0 的逆元一般都要设为 1.

有的时候 sqrt 会被卡精度,要比较精确时用 sqrtl,不放心的话自己手写!!!

邻接表清零的时候,h 数组清空的是点数而不是边数!!

写 splay 的时候,在找前驱和后继时先找完原值再取转完之后的根节点才是正确的,顺序不能改!!!!!!

写可持久化 Trie 时,注意 Trie 的 idx 一次修改最多能加几次。比如 insert 时:rt[i] = ++ idx; for(int i = K - 1; i >= 0; i --) work(); (假设 work 一次 idx 最多加 1)这段语句中,循环中 idx 修改了 K 次,但是不能无视外面多加的 1 次。这个对开空间有着决定性的作用,一定要搞清楚是 K 还是 K + 1!否则就会导致 RE!!!(P4592)

多测清空,强迫自己把所有东西要清空,自己还没有稳定的感觉的时候不要留不清空的数组。

扩展欧拉定理在使用时,一定要先确定模数有没有可能是 1,先把它特判掉再去做剩余的三条式子!!!

记住,等比数列求和公式q^0 = 1 开始

快速幂指数不能模 p

写一个特殊性质的分写完之后一定要记得 return 0!!!!!!!!

差分约束多测时因为用了 spfa 所以记得 st 数组也要清空。

二分的时候想清楚 l = 1 还是 l = 0。想清楚 r 是多少。不要偷懒,能确定 r 的范围的就不要直接 r=INF,而是把 r 算出来。

树剖路径查值是 while(top[u] != top[v])。建树的时候初值是新赋的值(nw数组)。

当用到栈的时候,记得检查用完栈之后 top 的值是不是所期望的值(0 或其他)。

赛场上改代码的时候每改一点就把所有大样例全部重测一遍。总之就是记得全部重测。

赛场上大样例很少的时候一定要写个暴力对拍。

欧拉路径的长度是边数 +1,空间一定要检查有没有开够。

用邻接矩阵存图求欧拉路径的时候,不要用 bool 存图,因为有重边也需要计算进去。

dp 的时候想一想初态,包括 f[0] 的状态,在优化的时候如果需要记录某个式子的最小值,那么一定要考虑需不需要记录在 f[0] 处的最小值。

注意一下 dp 的属性是 sum/max/min/...,在通读代码的时候一定要注意一下是不是这个属性。

重新开始检查的时候记得检查 for 循环开始定义的变量是否需要在循环内用到,以及是否用到了,且该用/不该用的地方是否用/没用了。

哈希的时候,模数如果超出了 int 范围的时候一定要记得写快速乘!!!否则就不要用,用 mod=999999937 相对安全一些。

解不定方程/不等式枚举解的时候,如果可以多枚举一些,尽量多枚举。参见 abc374e,可以两个变量枚举到 101,或者说就是不去判断你应该主要买哪一个,而是两种物品作为主要物品都枚举一下,在时间允许的情况下一定要保证枚举不出错,不会错过一些可能成为答案的值,不要冒风险!!

做前缀和的时候一定要注意两个端点的取值是否有可能超出远序列的取值,最好开大一些。(abc401f)

双指针的时候注意是否可能出现 l > r + 1 的情况,最好每次循环之后写上 l ++, r = max(r, l - 1);。(CF514D)

贪心的时候用 multiset,除非真的要用 set

对拍的代码写的时候一定要看清楚数据范围上下界,注意下界是 0 还是 1 还是别的数。

注意代码中 mp[x] 是否应为 mp.count(x)

桶排序一定要清空桶。