暑期训练狂刷系列——Hdu 1698 Just a Hook (线段树区间更新)

题目连接:

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

题目大意:

  有一个钩子有n条棍子组成,棍子有铜银金三种组成,价值分别为1,2,3。为了对付每场战斗需要对组成钩子某个区间的棍子进行调整。问经过q次调整后钩子的总价值是多少?

解题思路:

  线段树更新。因为数据范围的问题,每次更新到节点会TLE。用区间更新就会节省很多的时间,对每一个区间来讲,如果这个区间里面的棍子都是相同类型的,就用一个节点变量记录棍子类型,如果区间内棍子是不同类型,则将变量记录为-1。

 1 //#include <bits/stdc++.h>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 const int manx = 400000;
 8 struct node
 9 {
10     int l, r, x;
11     int Mid()
12     {
13         return (l+r)/2;
14     }
15 } tree[manx];
16 void build (int root, int l, int r)
17 {//建树,棍子都为铜质
18     tree[root].l = l;
19     tree[root].r = r;
20     tree[root].x = 1;
21     if (l == r)
22         return ;
23     build (2*root+1, l, tree[root].Mid());
24     build (2*root+2, tree[root].Mid()+1, r);
25 }
26 void update (int root, int l, int r, int s)
27 {
28     if (tree[root].l==l && tree[root].r==r)
29     {//当前区间都为s类型的棍子
30         tree[root].x = s;
31         return ;
32     }
33     else if (tree[root].x != -1)
34     {//当前区间棍子并不一样,需要把当前区间的状态转移到左右子树并标记当前区间
35         tree[2*root+1].x = tree[2*root+2].x = tree[root].x;
36         tree[root].x = -1;
37     }
38     if (r <= tree[root].Mid())
39         update (2*root+1, l, r, s);
40     else if (l > tree[root].Mid())
41         update (2*root+2, l, r, s);
42     else
43     {
44         update (2*root+1, l, tree[root].Mid(), s);
45         update (2*root+2, tree[root].Mid()+1, r, s);
46     }
47 }
48 int Sum (int root, int l, int s)
49 {
50     if (tree[root].x != -1)//当前区间棍子类型一样,则不再向下查询
51         return tree[root].x * (s - l + 1);
52     else
53     {
54         return Sum(2*root+1, l, tree[root].Mid()) + Sum(2*root+2, tree[root].Mid()+1, s);
55     }
56 }
57 int main ()
58 {
59     int t, l = 0;
60     scanf ("%d", &t);
61     while (t --)
62     {
63         int n, q;
64         scanf ("%d %d", &n, &q);
65         build (0, 1, n);
66         while (q --)
67         {
68             int a, b, x;
69             scanf ("%d %d %d", &a, &b, &x);
70             update (0, a, b, x);
71         }
72         int res = Sum(0, 1, n);
73         printf ("Case %d: The total value of the hook is %d.\n", ++l, res);
74     }
75     return 0;
76 }

 

  

posted @ 2015-07-02 17:09  罗茜  阅读(210)  评论(0编辑  收藏  举报