线段树

#define MAXSIZE 100
int sum[MAXSIZE << 2];

//建立线段树 基于完全二叉树

void build(int left,int right,int cur)
{
	//是叶子节点
	if (left == right)
	{
		sum[cur] = left;
		return;
	}

	//添加叶子节点
	int mid = (left + right) >> 1;
	build(left, mid, cur * 2);
	build(mid + 1, right, cur * 2 + 1);

	//叶子节点添加完成 添加父节点
	sum[cur] = sum[cur * 2] + sum[cur * 2 + 1];
}

//更新区间段

void update(int changeLeft,int changeRight,int updateValue,int curLeft,int curRight,int cur)
{
	//终止条件 不在更新区间
	if (curLeft > changeRight || curRight < changeLeft)
		return;
	//当前区间 在 更新区间内 不能这么做  因为子树没有更新 如果查询子树就gg了
	/*if (curLeft >= changeLeft && curRight <= changeRight)
	{
		sum[cur] = (curRight - curLeft + 1) * updateValue;
		return;
	}*/
	if (curLeft == curRight)
	{
		sum[cur] = updateValue;
		return;
	}

	int mid = (curLeft + curRight) >> 1;

	//检查左子树是否需要更新
	if (mid >= changeLeft)
	{
		update(changeLeft, changeRight, updateValue, curLeft, mid, cur * 2);
	}
	//检查右子树是否需要更新
	if (mid < changeRight)
	{
		update(changeLeft, changeRight, updateValue, mid + 1, curRight, cur * 2+1);
	}
	//更新当前节点
	sum[cur] = sum[cur * 2] + sum[cur * 2 + 1];
}
int query(int qLeft, int qRight, int curLeft, int curRight, int cur)
{
	//不在区间内
	if (curRight < qLeft || curLeft > qRight)
		return 0;
	//当前区间 在查询区间内
	if (curLeft >= qLeft && curRight <= qRight)
	{
		return sum[cur];
	}
	int result = 0;

	int mid = (curLeft + curRight) >> 1;
	//是否在左区间
	if (mid >= qLeft)
	{
		result+=query(qLeft, qRight, curLeft, mid, cur * 2);
	}
	//是否在右区间
	if (mid < qRight)
	{
		result+=query(qLeft, qRight, mid + 1, curRight, cur * 2 + 1);
	}
	return result;
}
int main()
{
	memset(sum, 0, sizeof(sum));
	memset(lazy, 0, sizeof(lazy));
	build(1, 10, 1);
	cout << query(3, 6, 1, 10, 1) <

//加入lazy标记

void push_down(int cur,int len)
{
	if (lazy[cur] == 0) return;

	lazy[cur * 2] = lazy[cur];
	lazy[cur * 2+1] = lazy[cur];

	sum[cur * 2] = lazy[cur * 2] * (len - len / 2);
	sum[cur * 2 + 1] = lazy[cur * 2 + 1] * (len / 2);

	lazy[cur] = 0;
}

//更新区间段

void update(int changeLeft,int changeRight,int updateValue,int curLeft,int curRight,int cur)
{
	//终止条件 不在更新区间
	if (curLeft > changeRight || curRight < changeLeft)
		return;
	//当前区间 在 更新区间内 不能这么做  因为子树没有更新 如果查询子树就gg了
	//给子树一个标志 下次查到子树的时候就更新
	if (curLeft >= changeLeft && curRight <= changeRight)
	{
		sum[cur] = (curRight - curLeft + 1) * updateValue;
		lazy[cur] = updateValue;
		return;
	}

	push_down(cur, curRight - curLeft + 1);
	//到叶子节点终止
	/*if (curLeft == curRight)
	{
		sum[cur] = updateValue;
		return;
	}*/

	int mid = (curLeft + curRight) >> 1;

	//检查左子树是否需要更新
	if (mid >= changeLeft)
	{
		update(changeLeft, changeRight, updateValue, curLeft, mid, cur * 2);
	}
	//检查右子树是否需要更新
	if (mid < changeRight)
	{
		update(changeLeft, changeRight, updateValue, mid + 1, curRight, cur * 2+1);
	}
	//更新当前节点
	sum[cur] = sum[cur * 2] + sum[cur * 2 + 1];
}
int query(int qLeft, int qRight, int curLeft, int curRight, int cur)
{
	//不在区间内
	if (curRight < qLeft || curLeft > qRight)
		return 0;
	//当前区间 在查询区间内
	if (curLeft >= qLeft && curRight <= qRight)
	{
		return sum[cur];
	}
	push_down(cur, curRight - curLeft + 1);

	int result = 0;

	int mid = (curLeft + curRight) >> 1;
	//是否在左区间
	if (mid >= qLeft)
	{
		result+=query(qLeft, qRight, curLeft, mid, cur * 2);
	}
	//是否在右区间
	if (mid < qRight)
	{
		result+=query(qLeft, qRight, mid + 1, curRight, cur * 2 + 1);
	}
	return result;
}

你可能感兴趣的:(数据结构)