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 }
代码君

 

你可能感兴趣的:(HDU)