算法竞赛之各种数据结构调试经验(坑点)贴

前言

我不想调试!!!

就是这样,本文诞生了

线段树

update函数

  • 没有在update函数里面pushdown和pushup
  • update的时候lazy标记是累加的而非赋值:
void update(int l,int r,int nl,int nr,int rt,ll w){
	if(l<=nl&&nr<=r){
		lazy[rt]+=w;//不能写成lazy[rt]=w;
		sum[rt]+=(nr-nl+1)*w;
		return;
	}
	pushdown(nl,nr,rt);
	int mid=(nl+nr)>>1;
	if(mid>=l)update(l,r,nl,mid,rt<<1,w);
	if(mid<r)update(l,r,mid+1,nr,rt<<1|1,w);
	pushup(rt);
}

数组大小

  • 数组没有开够,记得要开4倍大小

精度问题

  • 一般来讲数据都会特别鬼畜啊,记得开longlong

  • 特别注意有没有精度转化,即int相乘后面转longlong时可能在中间爆掉:

sum[rt]+=(long long)num*(nr-nl+1);//一定要转化精度

splay

1.关于插入极大和极小值这个技巧

一定要插入足够大和小的值,否则会出一些玄学错误,一定要能多大就多大
比如这个情况

2.关于rotate函数的不同写法

rotate函数理论上来说有不同的写法,但是原则就是一定要把那四个点的父子关系和相关信息维护正确
比如:在维护x的父子关系时,要确定y是x的哪个儿子,理论上可以通过:
1.原来x相对于y的位置关系
2.x的被影响的那个子节点相对于x的位置关系
两种方式来判断
这时问题来了,如果x没有子节点呢,这时x的子节点就是0(空都是0),那么这样就没有办法正确的更新父子关系,所以以后还是用前一种方法吧

3.关于insert函数

A

if(_p)tree[_p].son[_w>tree[_p].w]=_cur;

这一句特别容易被打掉!!!!!
如果不打的话,新插入的这个点的父节点就没法和这个点相连了

B

int _cur=root,_p=0;
while(_cur&&tree[_cur].w!=_w)
{
	_p=_cur;
	_cur=tree[_cur].son[_w>tree[_cur].w];
}

在寻找值为w的点时,while循环里面的判断条件是当前所在的点不为空!

这和find函数中的即将到达的点不为空需要区别

4.关于找第k大函数

while(1){
        if(tree[Lson(cur)].siz>=k)
            cur=Lson(cur);
        else if(tree[cur].cnt+tree[Lson(cur)].siz>=k){
            Splay(cur);
            return tree[cur].w;
        }
        else if(tree[cur].cnt+tree[Lson(cur)].siz<k){
        	k-=tree[cur].cnt+tree[Lson(cur)].siz;//
        	cur=Rson(cur);
		}
    }

注意第3个else if里面的两句话的顺序不可以换!
虽然很显然,但是在没有高度专注的情况下总是会出现这些神奇的情况

5.关于删点函数

记清楚步骤:先旋前驱到root,再旋后继到其前驱的下面
不能把后继旋到根上去了

6.关于找排名函数

在大部分定义里面,数m的排名为小于m的数的个数+1,不能忘记+1!

7.关于函数的返回值

有些函数返回值可以是某个点的值,也可以是某个点的编号
但是如果返回值,就不可以得到编号,若返回编号,却可以得到值
如果不做强行规定,在构建代码的时候会出现RE的风险
因此,规定如下:

  • _pos:返回_x的位置关系:0/1
  • update:void
  • rotate:void
  • splay:void
  • insert:void
  • find:void/int(int=>返回编号,不可返回值!)
  • findkth:int(返回编号)
  • pre:int(返回编号)
  • bac:int(返回编号)
  • del:void
  • getrank:int=>返回某个数的排名

8.关于宏的使用

由于结构体的特点,用结构体方式构建的Splay必然会显得比较冗杂,语句偏长容易积累bug且不容易调试,因此推荐以下宏定义:

#define f(x) tree[x].fa
#define Lson(x) tree[x].son[0]
#define Rson(x) tree[x].son[1]
#define ADX_son(x,w) tree[x].son[tree[x].w<w]
//按大小的儿子~~
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndrewMe8211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值