【題意】:總所周知,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