树状数组求区间最大值

写这篇博客的目的不是介绍树状数组求区间最大值的方法,而是想说,树状数组在支持单点修改+区间查询时对于区间最值的维护是错误的;
俺不知道其他的博客是咋写出来的,但是我今天在做一道题的时候,由于不想用线段树(其实是不会,忘了咋用)就去查了一下树状数组的方法,别说还真能查到,在这里就不放博客了;但是想说一些树状数组求区间最值的错误(在有值修改时候的错误)
初始:有一个tree的数组,其中tree[i]代表了a数组在[i-lowbit[i],i]区间上的最小值
在这种情况下,假定a[2]=1,并且在tree[4]上记录有tree[4]=1;此时a[3]=1;修改a[2]为2,这时向上传播,传到tree[4]的时候,tree[4]=min(tree[4],a[2]),这个时候这个值没有被修改,这是很合理的(因为这个最小值是由a[3]产生的)。
但是在刚才的讨论中如果a[3]=2;
tree[4]还是1,a[2]=1,此时,我要把a[2]的值改成2,发现我还是没改成功,为啥?a[2]还是比tree[4]大啊,必然改不了,但是这个时候就不对了,你把a[2]改成2的时候,这个tree[4]上的最小值不是由a[3]产生的了,所以这时候就出问题了;一些博客介绍查询的方法的确很新颖,但是更新就有问题,至少不应该用求和的方式去更新数组。
好了再说用线段树的方法,我认为线段树对付区间求最值就很用,你更新一个小子区间的时候,你能知道其他区间是啥情况,不会混到一起。

int lowbit(int x)
{
	return x & (-x);
}
//int build(int l, int r)//这个应该是O(logn)的复杂度
//{
//	for (int i = l; i < r; i++)
//	{
//		int t = i;
//		while (t < r)
//		{
//			tree[t] = min(tree[t], a[i].mn);//sort之后的
//			t = t + lowbit(t);
//		}
//	}
//}这块我觉得应该不用build之后直接更新就行了
void update(int L, int v, int r, int a)
{
	while (L < r)
	{
		if (a == -1)
		{
			if (v < tree[L])
			{
				tree[L] = v;
				count1[L] = 1;
			}
			else if (v == tree[L])
			{
				count1[L]++;
			}
		}
		else if (tree[L] == a)
		{
			if (count1[L] == 1)
				tree[L] = v;
		}
		L = L + lowbit(L);
	}
}
int query(int l, int r)
{
	int ans = INT_MAX;
	while (r >= l)
	{
		r--;
		for (; (r - lowbit(r)) >= l && r != 0; )
		{
			ans = min(ans, tree[r]);
			r = r - lowbit(r);
		}
	}
	return ans;
}

乐死了,用这个就图一乐吧,改一晚上了,发现是这有问题,heheheh

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值