// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css //目录导航 //生成目录索引列表

爆零小技巧合集【施工中】

#1

请观察

void mul(ll a[N][N],ll b[N],ll c[N]){
	memset(c,0,sizeof(c));
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			c[i]+=a[i][j]*b[j];c[i]%=mod;
		}
	}
}

有什么问题吗?问题出在 \(memset\) 上,这个函数传数组默认都是传指针的,所以 \(sizeof(c)\) 得到的是指针的长度,也就是 \(8\)

#2

这是个 \(FHQ\_Treap\) ,请观察:

int rank(int i,int num){
	//查找几个数比num小
	if(num==val[i]){
		return size[left[i]];
	}
	if(num<val[i])
		return rank(left[i],num);
	return size[left[i]]+count[i]+rank(right[i],num);
}

是的,没写递归边界, \(TLE\)

#3

与上面是同一份代码,还是 \(FHQ\_Treap\) ,不过与算法本身没啥关系,请观察:

void query(int i,int num,int ord,int &ans){
	if(i==0) return;
	if(ord==1){//1取前驱 
		if(val[i]<num){
			ans=std::max(ans,val[i]);
			query(right[i],num,ord,ans);
		}
		else query(left[i],num,ord,ans);
	}
	else if(ord==2){
		if(val[i]>num){
			ans=std::min(ans,val[i]);
			query(left[i],num,ord,ans);
		}
		else query(right[i],num,ord,ans);
	}
}
int getpre(int num){
	int ret=-1;
	query(head,num,1,ret);
	return ret;
}
int getnext(int num){
	int ret=INT_MAX;
	query(head,num,2,ret);
	return ret;
}

是的,将 \(val[i]\) 错用为 \(ord\) 了。

#4

又又又是同一份代码,请观察:

void update(int i){
	size[i]=count[i]+size[left[i]]+size[right[i]];
}
void changeCount(int i,int change){
	count[i]+=change;
}
void New(int num){
	val[++tot]=num;
	count[tot]=size[tot]=1;
	priority[tot]=rand()%1000;//随机分配优先级 
}
void add(int num){
	if(tot==0){
		New(num);
		head=1;
		return;
	} 
	int pos=find(head,num);
	if(pos!=0){
		changeCount(pos,1);
	}
	else{
		split(0,0,head,num);
		New(num);
		head=merge(merge(right[0],tot),left[0]);
	}
}

是的,直接修改单点值,导致祖先节点信息没能正确合并。

posted @ 2025-08-10 22:13  SSL_LMZ  阅读(6)  评论(0)    收藏  举报