Just a Hook(hdu 1698)

来源:互联网 发布:php ajax返回json数据 编辑:程序博客网 时间:2024/06/15 17:33

Just a Hook

TimeLimit: 4000/2000 MS (Java/Others)    Memory Limit:32768/32768 K (Java/Others)
Total Submission(s): 36149    Accepted Submission(s): 17638

ProblemDescription

In thegame of DotA, Pudge’s meat hook is actually the most horrible thing for most ofthe heroes. The hook is made up of several consecutive metallic sticks whichare of the same length.



Now Pudge wants to do some operations on the hook.

Let us number the consecutive metallic sticks of the hook from 1 to N. For eachoperation, Pudge can change the consecutive metallic sticks, numbered from X toY, into cupreous sticks, silver sticks or golden sticks.
The total value of the hook is calculated as the sum of values of N metallicsticks. More precisely, the value for each kind of stick is calculated asfollows:

For each cupreous stick, the value is 1.
For each silver stick, the value is 2.
For each golden stick, the value is 3.

Pudge wants to know the total value of the hook after performing theoperations.
You may consider the original hook is made up of cupreous sticks.

 

 

Input

The input consists of several test cases.The first line of the input is the number of the cases. There are no more than10 cases.
For each case, the first line contains an integer N, 1<=N<=100,000, whichis the number of the sticks of Pudge’s meat hook and the second line containsan integer Q, 0<=Q<=100,000, which is the number of the operations.
Next Q lines, each line contains three integers X, Y, 1<=X<=Y<=N, Z,1<=Z<=3, which defines an operation: change the sticks numbered from X toY into the metal kind Z, where Z=1 represents the cupreous kind, Z=2 representsthe silver kind and Z=3 represents the golden kind.

 

 

Output

For each case, print a number in a linerepresenting the total value of the hook after the operations. Use the formatin the example.

 

 

SampleInput

1

10

2

1 5 2

5 9 3

 

 

SampleOutput

Case 1: The total value of the hook is 24.

 

题意

   给定一个长度为N的区间,默认值为1,对区间进行Q次操作,每次将区间[x,y]的元素赋值为z(1<=z<=3)最后输出区间元素的总和。

 

思路

   线段树区间更新模板题,一定注意细节。

 

代码

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn = 1e5 + 500;#define node tree[id]#define lson tree[id*2]#define rson tree[id*2+1]int n, q;int a[maxn];struct Tree {int left, right, value, d;}tree[maxn * 4];void pushup(int id) {node.value = lson.value + rson.value;}void pushdown(int id) {if (node.d != 0 && node.left != node.right) {lson.d = rson.d = node.d;lson.value = node.d * (lson.right - lson.left + 1);//注意细节,闭区间的长度rson.value = node.d * (rson.right - rson.left + 1);node.d = 0;}}void build(int id, int le, int ri) {node.left = le;node.right = ri;node.d = 0;if (le == ri) {node.value = a[le];return;}int mid = (le + ri) >> 1;build(id * 2, le, mid);build(id * 2 + 1, mid + 1, ri);pushup(id);}int query(int id, int x, int y) {if (node.left >= x && node.right <= y) {return node.value;}pushup(id);pushdown(id);int ans = 0;int mid = (node.left + node.right) >> 1;if (x <= mid) ans += query(id * 2, x, y);if (y > mid) ans += query(id * 2 + 1, x, y);return ans;}void update(int id, int x, int y, int v) {if (node.left >= x && node.right <= y) {node.value = v * (node.right - node.left + 1);node.d = v;return;}pushdown(id);/*这里的pushdown是在多次更新时起作用,就是更新了好多次才查询一次,如果第一次更新之后没有query,那么线段树中某些结点它们的某个父节点的d应当是它们的value,但还未更新,这时如果不进行查询,直接第二次更新,那么之前的d就被覆盖了,结果也就错了。*/int mid = (node.left + node.right) >> 1;if (x <= mid) update(id * 2, x, y, v);if (y > mid) update(id * 2 + 1, x, y, v);pushup(id);}int main() {int t, x, y, v;scanf("%d", &t);for (int kase = 1; kase <= t; kase++) {scanf("%d%d", &n, &q);for (int i = 1; i <= n; i++) a[i] = 1;build(1, 1, n);while (q--) {scanf("%d%d%d", &x, &y, &v);update(1, x, y, v);}int ans = query(1, 1, n);printf("Case %d: The total value of the hook is %d.\n", kase, ans);}return 0;}