保留字:
distance,x1,x2,y1,y2,left,right,link,value
(本来觉得没啥必要,但是最近几天犯的傻逼错误太多了,我觉得有必要记录一下我的制杖行为
傻逼错误集合:
题中修改的是值我修改下标
查找函数没return
线段树区间修改没push_up
记录不容易找到的错误
lct如果想更新,某条边的权值的话不能先断开改值再连回去,应该splay边在lct中的点改值后pushup,因为即使题目保证这条边存在,它也未必在lct里
last_ans设初值。。。
注意如果两个int一个longlong相乘一定要先int乘longlong再乘int,如果先两个int乘再乘longlong依旧过会爆掉
在linux下这个程序会死的很惨:"cin>>n>>a[0].x>>a[0].y>>a[n+1].x>>a[n+1].y;"因为n默认值为0,但是在windows下是没有问题的
以后所有题尽量检查是否可能出现longlong,尤其注意乘法,提交之前把整个程序的乘法过一遍,两个int乘起来送给longlong这种事情太难看出来了
注意线段树的节点数要大于线段长度!!!!!!注意图的连通性!!!!!!注意图有没有环!!!!!!
图也有可能是一整个大强连通块,如果尝试用0节点做超级根的话这种情况容易翻车
数组的大小:线段树2倍,马拉车2倍,fft四倍(因为卷一遍后的长度就是卷的两个数组的长度的和)
再次强调最大值和最小值的初始值一定要根据题中给出的数据范围估算一下,最大值999999999还是有可能wa掉的(比如如果可能出现40000*40000就WA了),再水的题也不能放松警惕
并不是所有的四舍五入都要+0.5,如果保留n位小数就要加5e-(n+1),而且printf%.nlf自带四舍五入
//whlbnr(x,x+hd[0]-1,l,md),whlbnr(x+hd[0],y,md+1,r);这种写法非常危险!hd[0]很可能是全局变量,下一层递归的时候会更改全局的hd,然后再返回上一层进行第二次下一层递归的时候hd就变了
线段树似乎不会遇到这种问题,但是lct和splay区间加的时候不仅要加delta还要加value
多组数据一定记得初始化
lct注意,如果要修改一个点到根的路径,注意这里的根一般是原树根,需要先把原树根钦定成lct的根再access再修改
不知道我问什么总喜欢这样写for(int i=x;!isrt(x);i=fa[i]) stck[++tp]=fa[i];
lct中一切涉及儿子变化的都要pushup。。。比如cut。。。
平衡树旋转的时候x的size要放在temp前面求!!!!!!因为旋转过后x的深度比temp深,temp的size依赖于x
fft中最外面倍增长度的循环,i要<=N("for(int i=2;i<=N;i<<=1)")因为这里倍增的是长度,其他地方要枚举[0,N-1]是因为下标从0开始,但是外面倍增的是长度所以要<=N
fft其他容易写错的地方"_x=x[j]; _y=x[j+i/2]*w;"后面要*w,"for(N=1,L=0;N<max(l1,l2);N<<=1,++L); N<<=1,++L;"N<max(l1,l2)而不是<=,复数乘法很容易写错,要仔细检查
我不知道为什么总是会写成这样"if(mk==-1) for(int i=0;i<N;++i) a[i].r/=N;"……
ntt中求1/N是quck_power(N,mod-2)而不是quck_power(3,mod-2),因为求的是1/N么……
切记不要在多组输入中break,多行输出也不行,比如要输入m行,每行到某个数就可以判断答案了,但是这时候不能break,因为break会剩下一堆数留到下一行输入(但是程序并不知道这些数是上一行剩下来的
莫比乌斯反演的时候因为中间计算过程是在模意义下进行的,所以最终结果可能是现负数(但是因为结果是在模意义下的,所以答案实际上是对的),这个时候要调整成正数
用树状数组搞权值线段树的时候要注意,如果值可以是0,lowbit(0)还是0,修改和查询的时候x是根据lowbit变化的,如果出现0会死循环,所以0的情况还是要试
1e5的逆序对数可能会爆int,注意longlong(不只是逆序对数,任何点对都有可能爆longlong(除非有已知不会爆longlong的性质
煮席树新添版本的时候不能roots[++root_tot]=modify(roots[root_tot],balabala),因为这样会先自增root_tot,然后再调用roots[root_tot],这样roots[root_tot]就固定是0了,顺带一提,roots[root_tot++]=modify(roots[root_tot],balabala)这个写法也是错的
线段树重建时(赋上一个新初值)一定要清空delta(value不一定要清空,但是delta一定要
费用流的初见杀神坑,如果两个人在拆点费用流图上玩且路径不能相交,拆开的点就必须再连一条费用为0的边防止某人挡路影响最优解
网格图上搞id的时候注意如果因为题意网格图的坐标要进行调整(尤其是整个网格图的坐标要增大的时候),比如所有坐标增加d,求id就不能直接(x-1)*n+y-1,应该是(x-1)*(n+d)+y-1
接上,如果坐标可能是(0,0)求id就需要x*n+y,-1会出现负数,如果跑网络流,源为0的话最后还要再+1防止和源冲突
如果使用线段树把区间buff成一个值且buff上的值可能为0的话delta初值和空值就不能为0,要设成-1或着其他的东西
如果把所有点id-1然后用i<<1|1表示,点的值域是[0,n*2),如果用(i<<1)-1是[1,n*2],所有id-1然后用i<<1|1来表示这样容易把值域写成[0,(n-1)*2]
tarjian求强连通分量的编号跟节点最大,叶子节点最小
欧拉函数容易被写成酱:if(i%quq[j]){ phi[i*quq[j]]=phi[i]*quq[j]; break;}
1的欧拉函数可以是1,这个要根据具体题目来定?
cdq分治的时候注意遍历与修改与查询的关系,比如动态逆序对中当x递增的时候查找的是比y大的,因为虽然x是递增,但是修改上去的都是比当前x小的
线段树最好还是自保护一下,比较容易忘的是查询的左区间>查询的右区间
编译开警报后if(a=b)酱紫的会报错,这个时候if((a=b))就可以辣,这个是告诉编译器中间的等号就是赋值而不是手残打错
多组数据vector存图虽然不用memset_link,但是还是要清空的
线段覆盖问题中使用左端点+1右端点-1的方法,如果线段覆盖的是点,要在右端点右边-1,否则右端点不会被算上
平衡数中原始根节点不能是0(因为要判空),如果是其它的,也不能到原始跟就返回,因为原始跟下面可能还藏有节点(如果原始跟权值为-oo则有可能有节点在右儿子)
永远不要肯定自己的板子不会打错
cdq分治求星星点灯给x排序的时候要同时以y为第二优先级排序,不然会wa……(不知道为什么……
树上倍增多组数据的时候爸爸数组要清零,因为每次倍增查找2^i次爸爸的范围是1-16,上次的残留会被访问到
求1-n中间的数(奇数中间,偶数偏左)要用(n+1)>>1,如果n>>1,结果偶数一样,奇数是中间的左边
树上前缀和的时候要减一个lca和lca的爸爸(lca要留下)(这个是点权,如果是边权就减两个爸爸)
(其实下面的树上煮席树最好dfs序记一下dfs完了之后再修改,在dfs里面有爆栈的危险)
树上煮席树dfs的时候注意要先修改在往下dfs,因为后面的版本都是基于这个版本修改的
nim游戏中如果全是1答案刚好是反过来的(似乎是因为至少取一个),山神说博弈极端情况的特判比较多?
煮席树建原始线段树的时候要酱紫:get_SegmentTree(roots[root_cnt=tree_cnt=1]=1,1,n);,注意root_cnt=1的同时tree_cnt也要=1,也许换一种写法(比如返回节点id)会更优美?
NO和No和no这种东西……
位运算(尤其是状压)的时候注意第一个1是2^0,输出二进制检查和判断的时候都要注意
重点强调:1既不是质数也不是合数,但是phi[1]=1,这个有时候会用到
多维数组开错或调用错的错误也很难找出来,比如i<=200,j<=200,k<=4,开f[210][210][5],但是调用的时候是f[k][i][j],这样写可以完美艹翻小数据,但是大数据就gg了,比较难找
DP的时候还是要注意初值的问题,需要时刻注意重复使用的地方如果不重设初值会不会有影响
用字符数组的时候不要把下标为0的当做长度,char可以装数字但是只能装很小的数,似乎不超过200?
10^7的longlong在256M下似乎会炸?开出5*10^6以上的数组的时候都要认真计算一下空间……
double比较的时候还是谨慎一点,比如这两种写法上面的会ac,但下面的可能会wa掉,U*n 和 dinic 相等的时候差可能大于零,因为实际上相等 但是由于浮点误差导致u*n略大
不知道我为什么总是喜欢把last[e[i].y]=QUEUE[k],last_e[e[i].y]=i;写成last[e[i].y]=QUEUE[k],last_e[i]=i;这个需要注意一下= =
原来蛤习线性探测的时候要每次加一个稍大一点的数而不是每次+1……连蛤习都不会写,我tmd是有多弱
不膜答案的计数DP不开高精度都是强行被出题人耍流氓
round down是四舍五入,留心这个
结构体排序的时候留心一下如果其中一个元素存在相等的情况另一个元素顺序的混乱会不会对结果造成影响(比如要先按大小排序,再排id来去重,这个时候如果排大小的时候没有判断当大小相等时排id的话,就会造成大小相等的数id顺序混乱,最后WA掉)
打表或clock最好搞个醒目的标记(然而更多时候这并没有用╮(╯▽╰)╭
hash的范围也要比最多可能重复的个数大(好多)
如果因为出现负数但又要把负数作为下表而给负数加上某个数做下标的话,注意数组开双倍
存双向边的时候要注意边数组要开两倍,尤其注意用邻接链表搞网络流的时候要添加反向边也要开双倍
字符串排序要从后往前!因为前面优先级最大反而要在最后排
maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字
要改成Maintain
图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通 图不一定连通
位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低 位运算的优先级特别低
搞字符串的时候需要题目中描述字符串下标的语言,比如如果题目说第几个,下表就是从1开始的,但是搞字符串处理一般从0开始,这个时候就要判断
如果题目中没说数据保证合法,还是大开脑洞想几种可能出现的不合法的输入情况搞些特判上去吧……
for(int i=1;i<n;i++) temp_SA[--cnt_rank[rank2[i]]]=i;看上去挺和谐的,然而错了
后缀数组rank是从1开始的,rank为0的后缀(也就是SA[0])是'$'
用线段树查height的时候要注意rank[i]和rank[j]不一定那个大,需要判断一下
使用后缀数组查回文串或者找最长公共子序列的时候中间的分隔符和最后面添加的判重符不能一样,推荐使用'#'和'$'
搞后缀的最长公共前缀的时候因为height[i]是rank[i]和rank[i-1]的最长公共前缀,所以查RMQ的时候left要+1,left和right一般不会一样,但是要留意一下,如果有一样的情况要搞特判
在求height的函数里边所有height的下标全是rank[i],比如maxx=max(maxx,height[rank[i]]);,而且这个错误似乎不容易发现,尤其是求height的maxx的时候,因为如果是height[i],当前更新的是heignt[i1],等以后的某一i2刚好等于rank[i1],答案就被更新成对的了,但如果正确答案的rank[i]比i小,就不会更新到正确答案
BFS逐格染色的时候一定要记得判断边界,这个错误也很不容易发现,因为访问下标为负的地址不会报错而是覆盖,访问超出边界的地方不会用到
搞树归的时候(也许某些DP也适用),因为要枚举中间点,所以可能会重复算很多已经算过的状态,这个时候要判断一下
如果要用两个数乘出来的值赋值到longlong里边,这两个数必须至少有一个是longlong,如果两个都是int可能会在运算的时候炸掉
我现在已经弱到连高精乘单精都会写错的地步了QAQ,关于乘的结果长度的问题,在a[i]>=10往后推的时候要边推边更新长度,不能先推完了再更新长度,因为推完后可能因为%=10而出现中间==0的情况,但是边推边更新就不会出现这种问题,因为推之前没有%10,不会==0
最后的数据范围n,m什么的范围不一定要开成数组,比如P1822外星人弹吉他内题,只有6个弦,3000000个品丝,n是询问个数有5000000个,但是数组开[10][3100000]就够了
搞区间交之类的,给区间排序未必是左端点优先,比如【P1835】小红花,要右端点优先,然后从区间右边开始填东西,保证填的东西能覆盖到更多的区间
搞后缀数组的时候,在for(int i=1;i<=210;i++) cnt[i]+=cnt[i-1];这一步里,就算题目中说明输入的串在'A'到'Z'之间,也要这么做,因为还有一个'$'要统计,或者也可以吧后面内个判断符设置成char('A'-1)
如果最后求出来一个数a要膜另一个数b且a有可能是负的话,简便写法应该是(a%b+b)%b,而不是(a+b)%b,因为a的绝对值有可能很大,要先膜一下b使a的绝对值小于等于b
longlong这种东西如果用了就应该仔细检查一遍,几乎一切根longlong扯上关系的都要变成longlong,尤其是接收乘法结果或函数返回值的变量,还有函数的返回值
如果使用scanf("%s",s+1);来让输入的字符串初始下标为1,呢么获取这个串的长度应该strlen(s+1)
多组数据测试涉及到图的时候LINK一定要初始化!!!这个错误非常不容易被发现
剖的时候最后search的时候要注意查找左端点要是深度比较浅的内个点的标号+1,因为深度比较浅的内个点的值是它和它父节点之间连的边的值,但是在往同一个重链上攀的时候就不用这么判断了,因为不+1的话刚好把重链顶点和它的父节点之间的边算上了,就不用再算一遍了
而且最后内个search最好加一个判断if(x!=y),因为如果x==y,呢么线段树查询的左端点就会比右端点大
如果题目比较长或特别长一定要非常小心,因为长题面中很可能隐藏着什么奇奇怪怪的东西
想用指针了不要*,要&
超级傻逼的一次错误qaq:树剖时:x=father[x]……实际上应该是x=father[top[x]],之前直接多了整整几条链的复杂度qaq
DP的时候如果求最小值,需要注意一下方程中会不会出现+oo乘个数的情况,因为尽管不会对答案造成影响,但是很有可能会把int炸掉,比如BZOJ1003,方程中有dis[j+1][i]*(i-j),dis[j+1][i]可能是+oo,这时候如果不判断就炸了
注意手玩特殊数据,比如NOIP2010引水入城如果只有一行怎么办,0也是常用的特殊数据,计算中可能会除个0
记录傻逼的高精度错误
//for(int i=1;i<=x[0];i++) x[i]=f[_left][_right][i]+z;高精度+单精度不是这么写的qaq
正确做法:x[1]+=z
while(x[x[0]+1]){ x[0]++; x[x[0]+1]+=x[x[0]]/ss,x[x[0]]%=ss;}//如果没有每次都清空的话,会因为上一次遗留下来的数继续往后推
//for(int i=1;i<=nleft[0];i++)if(nleft[i]!=nright[i]) return nleft[i]>nright[i];高精度比较应该先比高位qaq
if(a)是判断a!=0,尽管这是个常识然而有时候还是会搞错成a>0
如果多重循环出现了诡异的bug,比如本来应该从(1,1)遍历到(4,5)但却只遍历了(1,1)和(4,5),这个时候重点检查多重循环里的变量使用,比如for(int k=1;i<=n;i++)
如果题中要求优先级,最好手玩个涉及到优先级的数据看一下
关于平衡树(SBT)的错误:
如果已经存在于平衡数中的权值也需要插入的话,可以记录某个节点上重叠了几个,这样进行个中操作都很方便
如果记录重叠了几个的话要在旋转中把重叠的个数转移到size上,本来想size只是维护平衡的,没有考虑到还牵扯到rank和select
maintainTMD是关键字(╯‵□′)╯︵┻━┻
需要注意0的意义,有些函数返回0作为没找到,但是如果0有意义的话很可能返回的这个有意义的0就被当成没意义了,比如郁闷的出纳员,工籽有可能是0,但是如果search以返回0作为没找的话就会WA
如果要乘后膜的话,最好还是longlong,即使题很水,也很有可能爆int
最大值还是初始化成-oo吧,还是要注意如果有负数最大值不能初始化成0
写区间buff查询区间和的时候,因为查询的是和,所以delta往左右子数的tvalue上转移的时候要乘上左右子数的区间长度(忽然发现我好像第一次做区间buff查询区间和,我好弱啊qaq)
如果要计算a-b且a要膜一个数的话a-b很可能变成负数,需要加上膜的数再膜
无论多简单的题多水的数据都不能小看,随便几个连乘就能把longlong炸掉,每一步都要膜
并查集的初始top并不是0而是自己的id,所以判断有没有到顶要用top[x]!=x
hash数组的范围对效率影响很大,尤其是如果将hash紧着最多重复的个数开,甚至开成和最多可能重复的个数一样,效率就会非常差(如果所有可能性都出现了,几乎每查询一次就要把hash数组扫一遍),比如最多重复1000000次,hash范围设为5000000,比设为1000000快4-5倍
有些DP的最优状态是能一直传到最后的,比如个中背包(至少目前已知二维背包是这样),这个时候要推到一下能不能最优质能不能传到最后再决定是否需要在中间去最优值(就是ans=max(ans,f[i][j])),这样可以防止被丧心病狂的出题人卡常(我当然是被卡了才来总结的这一点= =)
如果要多次计算最大流也要注意初始化
给mhz同学找的bug,sro_fhxb_cydiater_chad_chty_orz都没有找出来的错误(最后和chad一起找出来了):
程序大概是酱紫的:
for(int i=1;i<=n;i++){
scanf("%d",&temp);
for(int j=1;j<=temp;j++)
a[++top]=i;
}
最后问题是数组越界,n不大,但是乘上个temp后top就有可能很大
经验++
要取模的时候还是小心点负数,尤其是出现减法就要先膜再加再膜
如果因为出现负数但又要把负数作为下表而给负数加上某个数做下标的话,注意数组开双倍
基数排序top和桶一定记得清空!!!
状压的时候如果要判断k和i和j是否有冲突不能k&i&j,因为只要其中一个状态的某位是0,剩下两个状态这一位都是1的话也会&成0,但是这样是不合法的
题目中的描述有可能会和数据不符,如果发现问题(比如题中说是正整数,但是万一是0或负数咋办呐)尽量判断一