1. 程式人生 > >HDOJ1698 Just a Hook 線段樹區間更新

HDOJ1698 Just a Hook 線段樹區間更新

分析:一道比較裸的線段樹區間更新題,對比正常的線段樹問題,主要是每一次都對節點進行直接賦值,另外注意初始值為1。

程式碼:

#include  <iostream>
#include  <cstdio>
#include  <cstring>
using namespace std;
const int maxn = 100005;
int m, n, q, x, y, z;
struct Node {
	int left, right, value;
};
Node nodes[maxn << 2];
int add[maxn << 2];
void PushUp(int i) {
	nodes[i].value = nodes[i << 1].value + nodes[i << 1 | 1].value;
}
void PushDown(int i) {
	if(add[i] != 0) {
		int len = (nodes[i].right - nodes[i].left + 1);
		add[i << 1] = add[i];
		add[i << 1 | 1] = add[i];
		nodes[i << 1].value = add[i] * (len - (len >> 1));
		nodes[i << 1 | 1].value = add[i] * (len >> 1);
		add[i] = 0;
	}
}
void build(int i, int left, int right) {
	nodes[i].left = left;
	nodes[i].right = right;
	nodes[i].value = 0;
	if(left == right) {
		nodes[i].value = 1;
		return;
	}
	int mid = (left + right) >> 1;
	build(i << 1, left, mid);
	build(i << 1 | 1, mid + 1, right);
	PushUp(i);
}
void update(int i, int left, int right, int value) {
	if(nodes[i].left == left && nodes[i].right == right) {
		add[i] = value;
		nodes[i].value = value * (right - left + 1);
		return;
	}
	if(nodes[i].left == nodes[i].right) {
		return;
	}
	PushDown(i);
	int mid = (nodes[i].left + nodes[i].right) >> 1;
	if(right <= mid) {
		update(i << 1, left, right,value);
	} else {
		if(left >= mid + 1) {
			update(i << 1 | 1, left, right, value);
		} else {
			update(i << 1, left, mid, value);
			update(i << 1 | 1, mid + 1, right, value);
		}
	}
	PushUp(i);
}
int query(int i, int left, int right) {
	if(nodes[i].left == left && nodes[i].right == right) {
		return nodes[i].value;
	}
	PushDown(i);
	int mid = (nodes[i].left + nodes[i].right) >> 1;
	if(right <= mid) {
		return query(i << 1, left, right);
	} else {
		if(left >= mid + 1) {
			return query(i << 1 | 1, left, right);
		} else {
			return query(i << 1, left, mid) + query(i << 1 | 1, mid + 1, right);
		}
	}
}
int main() {
	scanf("%d", &m);
	for(int kase = 1; kase <= m; kase++) {
		memset(add, 0, sizeof(add));
		memset(nodes, 0, sizeof(nodes));
		scanf("%d", &n);
		scanf("%d", &q);
		build(1, 1, n);
		for(int i = 1; i <= q; i++) {
			scanf("%d%d%d", &x, &y, &z);
			update(1, x, y, z);
		}
		printf("Case %d: The total value of the hook is %d.\n", kase, query(1, 1, n));
	}
	return 0;
}