以下记录一些自己做题过程中遇到的问题/错误,以及自己总结出来的一些常见技巧和套路。
ps.这里仅为本人的主观理解,如有不对麻烦大家指出,谢谢w~!
一些做题技(tao)巧(lu)
想到就更。
- 数据范围较大,大于等于 的时候,又找不到公式,也不是杜教筛洲阁筛能解决的问题。考虑按根号/ 次分类。
- 某些跳几步跳几步的问题,一步一步跳太慢的话,一般都是用倍增表解决。
- 某些奇怪的数位题,如果需要记录的东西特别少,很有可能是直接bfs暴力解决。//当然也极有可能是数位dp//雾
- 某些求第k小/大的问题,转化为二分+统计比答案小/大的数的个数。
- 某些累乘问题如果结果特别大的,可以求对数转化为加法。
- 某些题面有关最短路的问题,一般是转化建边的方式,然后直接跑最短路即可。
- bitset:高端压位卡常题必备STL。//可以将复杂度/32,感觉特别有用,碰到了很多次。
- 看到【无向图中两点最大边权最小】想到kruscal,如果题中有涉及边权的计数问题,考虑在加入一条边的时候计算贡献。
- 容斥:解决求若干集合的并的元素个数,关键求出“至少…”的数量。
- 分治:考虑左边对右边的影响。
- 分块:数据结构题可以考虑一下。
- 集合的贡献与集合大小有关的计数题,常用的想法就是将集合的贡献分给每个元素。
危险/偏的错误
一些调试时遇到的奇怪错误/一般是一些调了很久,或者以前没遇到过,或者比较重要的错误:
- sqrt里面千万要强转Long double!!!因为假如是long long相乘以后就爆double了,sqrt()中默认是double。或者自己手写二分也行。实例:arc094 D。
- dp的初始化!太重要了!那种初值为0,1的都要写好!实例:cf960 F,最长上升子序列的初值为1,我没有设成1,极端数据就被叉掉了。考试时我无论如何都没有想到这个问题。
- 求log的时候直接将num不停/2就行,不要写二分,那样子似乎太慢了。实例:cf960 D。
- 注意阶乘和阶乘逆元预处理的时候,一定要for到0。实例:bzoj 1951;…太多了。
- 由于自定义的cmax是这样定义的:
#define cmax(x,y) (y)>(x)?(y):(x)
,相当于满足y>x的时候y会执行两次,假如y是一个线段树qry函数就tle了.以后各种地方都要注意这个问题。实例:hdu 5306。 - 在函数里传很多参数好像会变得很慢。一些分类讨论的题最好不要传参数进去,多写几个函数就行,代码长一点没什么关系(雾。实例:bzoj 4695。
- 乘法取模的时候注意如果一个因数大于模数要先%掉,否则小心爆long long。
- FFT预处理w[0/1][i]的时候,w[1][i]可以通过w[0][n-i]来得到,即
w[1][i]=w[0][n-i](i=0 to n-1)
。注意i是从0开始的,并且需要事先算好w[0][n]=(comp){1,0}
。实例:cf958F3。 - 大数乘积比较大小可以求对数以后转化为加法比较,但是千万注意精度问题!假如数非常大的时候一定要手写高精度。以及,高精度的比较注意从高位开始比,也就是循环要倒着写。
考场注意事项
- 题目千万要看仔细!不要有5000看成1000之类的错误。//然后写部分分的时候写了
if (n<=1000){....}
,结果它还是打包测评的,于是暴力分一分都没有了。gg。 - 最好暴力和各种部分分都写到
namespace
里(分清楚),小数据都用暴力跑,自己认为比较稳的部分分先判断掉写掉。 - 读优啥的(板子)千万不要写炸!!!尤其是样例特别小的时候,全是个位数,发现不了什么问题。
if
和while
不要写反。- 开
long long
不要忘记,以及大于模数的数要先取模。 - 各种初始化想清楚,千万不能含糊。检查时再看一遍。
- 实在想不出正经解法,可以尝试着…乱搞随机?大力猜结论?值得一试。
- 数据结构题/代码量稍大/细节较多的题,一定要记得对拍。哪怕是感觉很稳的数据结构,因为那只是自己感觉……。
- 碰到一眼看就被吓到感觉不会做的题,冷静一下,尝试最少的暴力分,以及有些可能写在中间的一些10/20的特殊性质部分分,或许比较容易得到。