HDU 1698 (线段树 区间更新) Just a Hook

有m个操作,每个操作 X Y Z是将区间[X, Y]中的所有的数全部变为Z,最后询问整个区间所有数之和是多少。

区间更新有一个懒惰标记,set[o] = v,表示这个区间所有的数都是v,只有这个区间被分开的时候再往下传递。

 1 #include <cstdio>
 2 
 3 const int maxn = 100000 + 10;
 4 int sum[maxn << 2], set[maxn << 2];
 5 
 6 int n, qL, qR, m, v;
 7 
 8 void build(int o, int L, int R)
 9 {
10     set[o] = 0;
11     if(L == R) { sum[o] = 1; return; }
12     int M = (L + R) / 2;
13     build(o*2, L, M);
14     build(o*2+1, M+1, R);
15     sum[o] = sum[o*2] + sum[o*2+1];
16 }
17 
18 void pushdown(int o, int L, int R)
19 {
20     if(set[o])
21     {
22         int M = (L + R) / 2;
23         int lc = o*2, rc = o*2+1;
24         set[lc] = set[rc] = set[o];
25         set[o] = 0;
26         sum[lc] = set[lc] * (M - L + 1);
27         sum[rc] = set[rc] * (R - M);
28     }
29 }
30 
31 void update(int o, int L, int R)
32 {
33     if(qL <= L && qR >= R)
34     {
35         set[o] = v;
36         sum[o] = v * (R-L+1);
37         return;
38     }
39     pushdown(o, L, R);
40     int M = (L + R) / 2;
41     if(qL <= M) update(o*2, L, M);
42     if(qR > M) update(o*2+1, M+1, R);
43     sum[o] = sum[o*2] + sum[o*2+1];
44 }
45 
46 int main()
47 {
48     //freopen("in.txt", "r", stdin);
49 
50     int T; scanf("%d", &T);
51     for(int kase = 1; kase <= T; kase++)
52     {
53         scanf("%d%d", &n, &m);
54         build(1, 1, n);
55         while(m--)
56         {
57             scanf("%d%d%d", &qL, &qR, &v);
58             update(1, 1, n);
59         }
60         printf("Case %d: The total value of the hook is %d.\n", kase, sum[1]);
61     }
62 
63     return 0;
64 }
代码君

 

posted @ 2015-04-26 15:07  AOQNRMGYXLMV  阅读(138)  评论(0编辑  收藏  举报