cdcq

梦幻小鱼干

导航

错误集合

线段树四倍

马拉车开两倍!(需要插入通配符)

有时候随手写个暴力很快,不用对拍,就在原代码里写,然后把输出比较,这样有时会让效率提高很多 

 

O 同下条,如果可能的话尽量测测答案为负数的数据

O 注意数组初值不一定是0,常见于要取max的ans数组或ans变量

如果真实答案是负数,那给变量赋0初值就死了

O 写封装的时候一定注意了,一般的写法不会用oop(数组模拟),那么下面这种写法就很笨比

void cpn(cmnd x,cmnd y){ x.l=y.l; x.r=y.r; x.v=y.v;}

这种写法只对形参进行了修改!影响不到外边

需要用索引找到真数据的位置改

void cpn(int x,int y){
nds[x].l=nds[y].l; nds[x].r=nds[y].r; nds[x].v=nds[y].v;
}

O 如果你企图用这种方法:printf("%d.%d",ans/100,ans%100)来以小数形式输出百分数,那就要自闭啦

问:102/100=? 102%100=? 102.0/100=?

O 张帆(主席)犯过的DP错误:dp[0][0][0]=0,其他都是-inf

第一维表示直到第i个物品,dp[i][j][k]从dp[i-1][j-1][k-1]和dp[i-1][j-1][k-3]转移

那么这样就会导致从第2个物品开始,(0,0)的状态不为0,相当于强制后面的物品上前面的车,不能从头选

应该给所有物品的(0,0)都初始化为0

为什么背包没有这个问题呢?

因为背包所有物品都dp在一个维度上呀,dp的时候一定要注意了

O 网格图的点数要特别注意

你以为是n个点?其实是n*m个点哒

这个在开数组,判断爆int等步骤都容易出错

O 一个dfs时复杂度分析的错误

我枚举n^2条边,对于每条边都花O(n)检查是不是树边,如果这条边是树边(n-1条),那么就枚举选或不选并搜下一层

这样其实并不是2^n*n的复杂度,因为n^2的枚举和2^n的枚举是相互交织的,n^2并不能被2^n覆盖掉,总复杂度差不多还是2^n*n^3量级

所以还是别偷懒用O(n)检查,先用并查集预处理出树边再搜吧。。

O 当通过返回oo来控制二分中贪心的无解的时候

注意是否会爆int(很可能会的,所以还是慎用oo啊,用了尽量开longlong吧)

O 当你在递归或dfs中使用队列或栈的时候一定要小心了!

大多数时候所有的递归层数共用一个队列,如果不退栈将导致可怕的后果

事实上,即使保证每个点至多只入队一次,如果多层递归同时用一个栈的话,还是必须记录当前层的栈顶位置

所以还是尽量避免多层共用吧,先预处理好,再一次性做完队列该做的事

O 用阶乘预处理法求组合数时一定注意,注意检查阶乘预处理的范围

尤其是方格里求组合数,阶乘的范围是[0,n+m-2]而不是[0,n],也不是[1,n],注意求0

如果只预处理了0到n交上去必WA,肯定又要怀疑结论错了,损失惨重,切记啊!

这个易错点再次说明手测最大数据的必要性

O id函数初始化和统计答案的时一定注意!

统计的不是1到n,而是0到id(n,m)(或者别的范围)

id函数易错点,只要出现id函数必须列入常规项检查

O 多维id函数解压易错点:如果id=x*m*4+y*4+z,那么y=id/4%m而不是id%m/4,注意顺序

O 使用id函数压缩状态的时候一定注意最小的id是不是0,以及会不会造成影响!!!

例如last[t]!=0这个判断,就可能在id为0的状态前停下,而不是一条链的开始停下

再比如初始化的时候,容易写成从1到idmax初始化,把0漏掉导致错误

O 一个剪枝中的贪心错误

左边有n个点有一个权值a[i],如果这个点总共被选d次,那么它对答案的贡献就是a[i]^d

右边有n个点,每个点必须选择一个左边的和这个点连边的点

思考:启发式函数中,右边的某个点对答案的启发式函数h是否能设置为与它连边的所有点中a最小的那个?

不是!

当a=1时,如果某个点第二次被选,它对答案的贡献是0而不是至少是1

O 如果数据不是特别大,不妨先写一个简单的启发式函数,TLE了再尝试优化,不要一上来就写很复杂的启发式函数,导致出错就得不偿失了

O 读入字符串时字符串的数组一定不要开成刚好的大小!!!

因为scanf读入后会添一个\0,如果数组大小刚好就越界了。。。

所以还是不要省什么内存了,每个数组都尽量有点冗余,免得又有什么奇奇怪怪的错误

O 判断所有的点能否到达T一定不能偷懒原图bfs或dfs!

必须建反向图

O 倍增求lca的注意事项:

注意如果要同时维护区间和,区间最大值的时候(边权),最后x和y往lca合并的时候,由于二者是从同深度共同向上,因此两人的(边的)值都要考虑到

if(x==y)  return mx;

else return max(mx,max(mst[y][0],mst[x][0]));

O 计算几何检查点:跟eps比的东西有没有abs

没加abs就傻b了哈哈

O 不管是手写堆还是用STL,比较优先级的时候切忌进行dis[x]>dis[y](dis是全局数组)这种比较

因为dis会变,堆里用来比较的dis不是入堆时的值,修改dis会导致堆结构混乱

O 大坑!python读入字符串的时候会去掉\n但是不会去掉\r,所以python尽量避免全句匹配!

\r一般是windows在记事本里手打数据造成的

O 幂取模的时候注意指数要对(mod-1)取模

检查的时候注意有些计算函数可能放在指数上面,函数里的模数也要是mod-1

O 一种错误的DP写法:

O dfs回溯的时候注意检查完全,不要光盯着循环里看,函数开头dfn类似的可能也要回溯

O 给你一个区间的左端点和长度,范围1e9,那么坐标的范围是2e9而不是1e9,因为1e9+1e9=2e9

O 要求你统计字符串中出现的字符中出现的次数并升序输出,注意没出现的字符可是不输出的哦。。。

O 10点40的时候时针不在10上!涉及到钟表的几何问题可能掉坑

O 如果把2位小数转整数,(long long)(b*100)不可取,b=0.57时得到0.56,应该+eps

O double的有效位数大概到16为,一个1e15的整数乘一个两位小数,再转成longlong就可能丢精度了,应该给小数乘100再除回去

O double强转int的时候注意可能要加括号,例如(int)a*b,如果a是整数b是浮点数,而想让a*b变成浮点数就傻了,应该(int)(a*b)

O 如果要输出整数部分,注意算清数据范围,有时候不能用(int)a而是(long long)a

O 两个值为1e10的long long相乘结果大于0

O 用multiset的时候,注意erase是删除所有相等元素,并返回删除元素的个数

O 注意别把2e5的数组开成1e5

O 鸡兔同笼问题中,有a个头,b只脚,判断数据是否可能的条件不是2a<=b<=4b,而是b%2==0 && 2a<=b<=4b!

O 强连通分量缩点+拓扑排序千万不能偷懒不缩点!!

不缩点而用标号代替的后果不仅是WA(拓扑DP的最优值有滞后性),还会RE(不缩点是假dag,还是有环的)

O 用余弦定理时注意判断是否构成三角型,3中情况都必须判断到,很容易漏

O 直角坐标转极坐标的时候注意α不是arccos(Δx/l),arccos的范围是[0,pi],还需要判定Δy

O 长度为0的序列错位排序方案数是1不是0

O 如果对dp的f数组做前缀和,注意f的初始状态如果不为0,那么前缀和中,对应一层的初值都不为0

O 有些dp使用滚动数组可以直接赋值,无需清空数组,但是注意有一些赋值不到的地方(比如f[i][0])可能需要清空

O 出现灵异错误时可以注意一下局部变量是不是没初值,尽管这个错误在初学者里很常见,但熟练者一旦出现实际更为棘手

O 线段树区间赋值注意delta的空值是否能为0,因为区间赋值很多时候都存在把区间赋值为0的情况,这时delta空值不能是0

O 检查数组大小时要注意某些值的范围可能变化,例如缩点+背包,那么包的容量可能就会增大

O SPFA(包括费用流)队列长度应该比点数多,因为可能重复进队

O 用字符数组的时候不要把下标为0的当做长度,char可以装数字但是只能装很小的数

O 浮点数比较相等的时候,注意是abs(a-b)<eps,而不是a-b<eps

O 有时候sort会巨慢,如果次数比较多就很难受

这时如果结构体排序,可以在比较函数前加'&',即参数取地址,防止每次函数调用都把结构体复制一遍,可以跑得飞快

当然也可以手写堆排序,难度不大

O 浮点数二分不能这么写:

应该算出循环次数后直接for,否则在32位机上会因为精度问题死循环

O 如果main函数里ans没有初值,而ans相关的语句只有ans=min(ans,...)和cout,编译器是不会报错的(可能是把min那句当成赋值了)

这个时候会一定概率输出正确答案,当ans初值随到比答案大的时候就正确,否则WA 233

O 用printf四舍五入时需要+eps,防止丢精度

O 字词删除的权值线段树不能这么写(功能是找给定范围内的权值最大值)

if(z<=md) return qry(x<<1,l,md,z);
else return max(qry(x<<1,l,md,z),qry(x<<1|1,md+1,r,z));

会T飞,要这么写:

if(z<=md) return qry(x<<1,l,md,z);
else if(z<=r) return max(qry(x<<1,l,md,z),qry(x<<1|1,md+1,r,z));
else if(v[x<<1|1]) return qry(x<<1|1,md+1,r,z);
else return qry(x<<1,l,md,z);

 

posted on 2019-08-03 16:58  cdcq  阅读(295)  评论(0编辑  收藏  举报