20pts 警示后人
查看原帖
20pts 警示后人
316358
不知名用户楼主2023/6/7 19:20

如果你用线段树 AC 了 #1 和 #10,你的问题很可能是我说的。

考虑左子树对右子树影响,右子树不能顺手更新,只是合并到节点时考虑影响。

错误示例(更改了右子树):

int calc(int p, long double pre)
{
	if(st[p].l==st[p].r)
		return st[p].cnt = (st[p].mx > pre);
	else
		if(st[p*2].mx>pre)
			return st[p].cnt = (calc(p*2,pre) + st[p].cnt - st[p*2].cnt);
		else
			return st[p].cnt = calc(p*2+1,pre);
}

void change(int p, int x, long double d)
{
	int mid = st[p].l + st[p].r >> 1;
	if(st[p].l==st[p].r)
	{
		st[p].mx = d;
		st[p].cnt = 1;
		return;
	}
	if(x<=mid) change(p*2,x,d);
	else change(p*2+1,x,d);
	calc(p*2+1,st[p*2].mx);
	st[p].cnt = st[p*2].cnt + st[p*2+1].cnt;
	st[p].mx = max(st[p*2].mx,st[p*2+1].mx);
}

正确示例:

int calc(int p, long double pre)
{
	if(st[p].l==st[p].r)
		return st[p].mx > pre;
	else
		if(st[p*2].mx>pre)
			return calc(p*2,pre) + st[p].cnt - st[p*2].cnt;
		else
			return calc(p*2+1,pre);
}

void change(int p, int x, long double d)
{
	int mid = st[p].l + st[p].r >> 1;
	if(st[p].l==st[p].r)
	{
		st[p].mx = d;
		st[p].cnt = 1;
		return;
	}
	if(x<=mid) change(p*2,x,d);
	else change(p*2+1,x,d);
	st[p].cnt = st[p*2].cnt + calc(p*2+1,st[p*2].mx);
	st[p].mx = max(st[p*2].mx,st[p*2+1].mx);
}
2023/6/7 19:20
加载中...