HDU - 1698 区间修改 + 线段树

一、内容

题意:给定一个区间,初始值都是1,和几组询问,每次询问将一段区间修改成某个值,最后求所有区间的和。

二、思路

  • 用一个数组sum进行lazy标记和下放就可以了, 如果这个区间有多个数那么这个区间sum[id] = -1, 若这个区间全部是一个相同的数那么sum[id]=相同数
  • 进行pushdown()的时候,只需要讲左右儿子区间赋值为sum[id], sum[id] = -1即可
  • 最后query() 统计所有区间的和

三、代码

#include <cstdio> 
#include <cstring>
using namespace std;
const int maxn = 1e5 + 5;

int t, x, y, z, n, q, sum[maxn << 2], ans;
void pushdown(int id) {
	if (sum[id] == -1) return;
	sum[id << 1] = sum[id << 1 | 1] = sum[id];
	sum[id] = -1;
} 

void update(int id, int l, int r, int x, int y, int z) {
	if (x <= l && r <= y) {
		sum[id] = z;
		return;
	}
	pushdown(id);
	int mid = (l + r) >> 1;
	if (x <= mid) {
		update(id << 1, l, mid, x, y ,z);
	}
	if (y > mid) {
		update(id << 1 | 1, mid + 1, r, x, y, z);
	}
}
void query(int id, int l, int r) {
	if (sum[id] != -1) {
		ans += sum[id] * (r - l + 1);
		return;	
	}
	int mid = (l + r) >> 1;
	query(id << 1, l, mid);
	query(id << 1 | 1, mid + 1, r);
}

int main() {
	scanf("%d", &t);
	for (int size = 1; size <= t; size++) {
		memset(sum, -1, sizeof(sum));
		scanf("%d%d", &n, &q);
		sum[1] = 1; //初始全部都是铜
		for (int i = 1; i <= q; i++) {
			scanf("%d%d%d", &x, &y, &z);
			update(1, 1, n, x, y, z);
		} 
		ans = 0;
		query(1, 1, n);
		printf("Case %d: The total value of the hook is %d.\n", size, ans);
	}
	return 0;
}
发布了346 篇原创文章 · 获赞 254 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_41280600/article/details/100822214