hdu 1698 Just a Hook(线段树区间更新)

http://acm.hdu.edu.cn/showproblem.php?pid=1698

/*
本题题意
     给定 t 组测试用例, 每组测试用例给定长度为n
     的分数, 每个分数的初始值为1, 给定m组查询方法
     查询方法 包括更新一个区间的分数为 1(铜钩子的分数), 或者 2(银钩子的分数) 或者 3(金钩子的分数), 最后需要输出整个
     区间的值
本题思路:
    此题需要更新整段区间的值, 查询,更新区间的值, 可以使用线段树
     可以在单点更新线段树外套一个for循环, 但是这样时间复杂度很高会
     到o(n2) 因此需要添加懒惰标记, 当遍历的树结点的左右子树对应的数组区间
     不在查询时或更新条件的区间范围 l , r时就需要下放懒惰标记.
*/

#include<bits/stdc++.h>
using namespace std;
const int maxsize = 100005;
struct Node {
	int l, r, sum, lazy;
	update(int data) {
		sum  = (r - l + 1) * data; // 本题是更新到 不是在原基础上增加
		lazy = data; // 本题是更新到 不是在原基础上增加 
	}
}tree[maxsize * 4];
int hook[maxsize];
void push_up(int x) {
	tree[x].sum = tree[x<<1].sum + tree[x<<1|1].sum;
}
void push_down(int x) { // 下方懒惰标记的值 
	if(tree[x].lazy != 0) {
		tree[x<<1].update(tree[x].lazy);
		tree[x<<1|1].update(tree[x].lazy);
		tree[x].lazy = 0;	
	}
}
void build(int x, int l, int r) { // 建树 
	tree[x].l = l, tree[x].r = r;
	tree[x].sum = tree[x].lazy = 0;
	if(l == r) {
		tree[x].sum = hook[l];
	} else {
		int mid = (l + r) / 2;
		build(x<<1, l , mid);
		build(x<<1|1, mid + 1, r);
		push_up(x);
	}
}
void update(int x, int l, int r, int data) { // 更新树的结点 
	int L = tree[x].l, R = tree[x].r;
	if(L >= l && R <= r) {
		tree[x].update(data);
	} else {
		push_down(x);
		int mid = (L + R) / 2;
		if(mid >= l) update(x<<1, l, r, data); 
		if(mid < r) update(x<<1|1, l, r, data);
		push_up(x);
	}
}
int query(int x, int l, int r) { // 查找树的结点 
	int L = tree[x].l, R = tree[x].r;
	if(L >= l && R <= r) {
		return tree[x].sum;		
	} else {
		push_down(x);
		int mid = (L + R) / 2, res = 0;
		if(mid >= l) res += query(x<<1, l, r);
		if(mid < r) res += query(x<<1|1, l, r);
		return res;
	}
}
int main() {
	int t, n, m, cnt = 1;
	scanf("%d", &t);
	while(t--) {
		scanf("%d%d", &n, &m);
		for(int i = 1; i <= n; i++) {
			hook[i] = 1;
		}
		int l, r, data;
		build(1, 1, n);
		for(int i = 0; i < m ;i++) {
			scanf("%d%d%d", &l, &r, &data);
			update(1, l, r, data);
		}
		//int ans = tree[1].sum;
		int ans = query(1, 1, n);
		printf("Case %d: The total value of the hook is %d.\n", cnt++, ans); 
	} 
	return 0;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值