HDU 1698 Just a Hook

题意:(用通俗的语言描述)T组数据,每组数据第一行是一个数N,表示有N个数(初始都为1),第二行是一个数M,代表接下来有M组输入,每组输入三个数X,Y,Z,分别代表将[X,Y]区间的值改为Z,询问最后N个数的和。对于样例解释:初始的N为:1 1 1 1 1 1 1 1 1 1  sum = 10,操作之后:2 2 2 2 3 3 3 3 3 1 sum= 24,然后输出。

考察的是线段树的区间更新(延迟更新)。因为查询的是总区段的和,所以不需要进行查询操作了,具体请看代码:

//通常写法   904ms
#include <stdio.h>
const int maxn = 1e5+5;
struct Node{
	int l, r;
	int lazy;
	int value;
	int mid() {
		return (l+r)>>1;
	}
}node[maxn<<2];

void Pushdown(int i, int m) {
	if(node[i].lazy) {
		node[i<<1].lazy = node[i].lazy;
		node[i<<1|1].lazy = node[i].lazy;
		node[i<<1].value = node[i].lazy*(m-(m>>1));
		node[i<<1|1].value = node[i].lazy*(m>>1);
		node[i].lazy = 0;
	}
	return ;
}

void Build(int i, int l, int r) {
	node[i].l = l;
	node[i].r = r;
	node[i].lazy = 1;
	if(l == r) {
		node[i].value = 1;
		return ;
	}
	int m = (l+r)>>1;
	Build(i<<1, l, m);
	Build(i<<1|1, m+1, r);
	node[i].value = node[i<<1].value+node[i<<1|1].value;
	return ;
}

void Update(int i, int l, int r, int C) {
	if(node[i].l == l && node[i].r == r) {
		node[i].lazy = C;
		node[i].value = C*(r-l+1);
		return ;
	}
	if(node[i].l == node[i].r) return ;
	Pushdown(i, node[i].r-node[i].l+1);
	int m = node[i].mid();
	if(r <= m) Update(i<<1, l, r, C);
	else if(l > m) Update(i<<1|1, l, r, C);
	else {
		Update(i<<1, l, m, C);
		Update(i<<1|1, m+1, r, C);
	}
	node[i].value = node[i<<1].value + node[i<<1|1].value;
	return ;
}

int main() {
	int T, N, M;
	int X, Y, Z;
	int Case = 1;
	scanf("%d", &T);
	while(T--) {
		scanf("%d", &N);
		Build(1, 1, N);
		scanf("%d", &M);
		while(M--) {
			scanf("%d %d %d", &X, &Y, &Z);
			Update(1, X, Y, Z);
		}
		printf("Case %d: The total value of the hook is %d.\n", Case++, node[1].value);
	}
	return 0;
}
//另一种写法   858ms
#include <stdio.h>
const int maxn = 1e5+5;
struct Node{
	int lazy;
	int value;
}node[maxn<<2];

void Pushdown(int i, int m) {
	if(node[i].lazy) {
		node[i<<1].lazy = node[i].lazy;
		node[i<<1|1].lazy = node[i].lazy;
		node[i<<1].value = node[i].lazy*(m-(m>>1));
		node[i<<1|1].value = node[i].lazy*(m>>1);
		node[i].lazy = 0;
	}
	return ;
}
void Build(int i, int l, int r) {
	node[i].lazy = 0;
	node[i].value = (r-l+1);
	if(l == r) return ;
	int m = (l+r)>>1;
	Build(i<<1, l, m);
	Build(i<<1|1, m+1, r);
}
void Update(int i, int l, int r, int left, int right, int C) {
	if(l <= left && r >= right) {
		node[i].lazy = C;
		node[i].value = C*(right-left+1);
		return ;
	}
	if(left == right) return ;
	Pushdown(i, right-left+1);
	int m = (left+right)/2;
	if(l <= m) Update(i<<1, l, r, left, m, C);
	if(r > m) Update(i<<1|1, l, r, m+1, right, C);
	node[i].value = node[i<<1].value + node[i<<1|1].value;
	return ;
}
int main() {
	int T, N, M;
	int X, Y, Z;
	int Case = 1;
	scanf("%d", &T);
	while(T--) {
		scanf("%d", &N);
		Build(1, 1, N);
		scanf("%d", &M);
		while(M--) {
			scanf("%d %d %d", &X, &Y, &Z);
			Update(1, X, Y, 1, N, Z);
		}
		printf("Case %d: The total value of the hook is %d.\n", Case++, node[1].value);
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值