【題意】:總所周知,Dota里面有個屠夫,他有個吊鉤。現在考慮他的吊鉤由n(n<=100000)段小棒組成,初始時,都是銅棒。給出q(q<=100000)個操作,每個操作都可以把第i段到第j段的小棒替換成其他類型的棒(銅棒,銀棒,金棒,價值分別為1,2,3)。問,經過q個操作之后,這個吊鉤的總價值為多少。

【題解】:線段樹,區間替換,區間查詢。
               初學線段樹,理解延遲標記是關鍵。
               本題比較特殊,查詢只有一次,而且是查詢整個區間,輸出stick[1]即可。

【代碼】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 using namespace std;
 8 #define pb push_back
 9 #define lc(x) (x << 1)
10 #define rc(x) (x << 1 | 1)
11 #define MAX 100005
12 int stick[MAX<<2], n, m;
13 int lazy[MAX<<2];
14 
15 void pushup(int p) {
16     stick[p] = stick[lc(p)] + stick[rc(p)];
17 }
18 
19 void pushdown(int p, int len) {
20     if(lazy[p]) {
21         lazy[lc(p)] = lazy[rc(p)] = lazy[p];
22         stick[lc(p)] = (len - (len >> 1)) * lazy[p];
23         stick[rc(p)] = (len >> 1) * lazy[p];
24         lazy[p] = 0;
25     }
26 }
27 
28 void build(int l, int r, int p) {
29     lazy[p] = 0;
30     if(l == r) {
31         stick[p] = 1;
32         return;
33     }
34     int mid = (l + r) >> 1;
35     build(l, mid, lc(p));
36     build(mid + 1, r, rc(p));
37     pushup(p);
38 }
39 
40 void update(int L, int R, int c, int l, int r, int p) {
41     if(L <= l && r <= R) {
42         lazy[p] = c;
43         stick[p] = c * (r - l + 1);
44         return;
45     }
46     pushdown(p, r - l + 1);
47     int mid = (l + r) >> 1;
48     if(L <= mid) update(L, R, c, l, mid, lc(p));
49     if(R > mid) update(L, R, c, mid + 1, r, rc(p));
50     pushup(p);
51 }
52 
53 int main() {
54     int T, Case = 1;
55     int x, y, z;
56     scanf("%d", &T);
57     while(T--) {
58         scanf("%d%d", &n, &m);
59         build(1, n, 1);
60         while(m--) {
61             scanf("%d%d%d", &x, &y, &z);
62             update(x, y, z, 1, n, 1);
63         }
64         printf("Case %d: The total value of the hook is %d.\n", Case++, stick[1]);
65     }
66     return 0;
67 }
68