AC后的疑问
查看原帖
AC后的疑问
131591
蒟蒻君HJT泽渡透香楼主2022/4/1 20:16

本蒟蒻看了题解,然后自己写了一份SAM+倍增+线段树合并的版本,起初merge用传参版本,一直WA,函数代码如下:

void merge(int &x,int &y,int l,int r){
	if(!x){
		x=++tot;
		tree[tot]=tree[y];
		return ;
	}
	if(!y) return ;
	int z=++tot;
	if(l==r){
		tree[z].Mc=tree[x].Mc+tree[y].Mc;
		tree[z].M=l;
		x=z;
		return ;
	}
	int mid=l+r>>1,ls,rs;
	merge(tree[x].ls,tree[y].ls,l,mid);
	merge(tree[x].rs,tree[y].rs,mid+1,r);
	ls=tree[x].ls,rs=tree[x].rs;
	tree[z].ls=tree[x].ls,tree[z].rs=tree[x].rs;
	if(!ls) tree[z].M=tree[rs].M,tree[z].Mc=tree[rs].Mc;
	else if(!rs) tree[z].M=tree[ls].M,tree[z].Mc=tree[ls].Mc;
	else {
		tree[z].Mc=max(tree[ls].Mc,tree[rs].Mc);
		if(tree[ls].Mc>=tree[rs].Mc) tree[z].M=tree[ls].M;
		else tree[z].M=tree[rs].M;
	}
	x=z;
	return ;
}

后来换成了int返回合并后的节点编号的版本,就过了,请问dl们这是为什么呢? int版本代码如下:

int merge(int x,int y,int l,int r){
	if(!x || !y) return x|y;
	int z=++tot;tree[z]=tree[x];
	if(l==r){
		tree[z].Mc+=tree[y].Mc;
		tree[z].M=l;
		return z;
	}
	int mid=l+r>>1,ls,rs;
	tree[z].ls=merge(tree[x].ls,tree[y].ls,l,mid);
	tree[z].rs=merge(tree[x].rs,tree[y].rs,mid+1,r);
	ls=tree[z].ls,rs=tree[z].rs;
	tree[z].Mc=max(tree[ls].Mc,tree[rs].Mc);
	if(tree[ls].Mc>=tree[rs].Mc) tree[z].M=tree[ls].M;
	else tree[z].M=tree[rs].M;
	return z;
}

其中,M保存出现次数最多的字符串的编号,Mc保存出现次数。

2022/4/1 20:16
加载中...