hdu1698(线段树区间更新)

题目链接:http://hdu.hustoj.com/showproblem.php?pid=1698

题意:没啥好说的,读题吧(;¬_¬)

思路:典型的线段树区间更新

代码:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int maxn = 1e5 + 10;
 5 struct segTree
 6 {
 7     int left, right;
 8     int val;
 9     int addMark;    //延迟标记
10 } segTree[maxn * 4];
11 
12 void pushUp(int rt)    //更新父节点值
13 {
14     segTree[rt].val = segTree[rt * 2].val + segTree[rt * 2 + 1].val;
15 }
16 void build(int l, int r, int rt)
17 {
18     segTree[rt].addMark = 0;
19     segTree[rt].left = l;
20     segTree[rt].right = r;
21     segTree[rt].val = 1;    //刚开始都是铜棒1
22     if(l == r)
23     {
24         return;
25     }
26     int mid = (l + r) / 2;
27     build(l, mid, rt * 2);
28     build(mid + 1, r, rt * 2 + 1);
29     pushUp(rt);
30 }
31 
32 void pushDown(int rt)    //更新延迟标记
33 {
34     if(segTree[rt].addMark != 0)    //被标记了
35     {
36         //延迟标记传递更新
37         segTree[rt * 2].addMark = segTree[rt].addMark;    //因为这里是直接改变,只记录最后结果,所以不用+=。eg:铜变银再变金,只记录金即可
38         segTree[rt * 2 + 1].addMark = segTree[rt].addMark;
39         //节点值传递更新
40         segTree[rt * 2].val = segTree[rt].addMark * (segTree[rt * 2].right - segTree[rt * 2].left + 1);
41         segTree[rt * 2 + 1].val = segTree[rt].addMark * (segTree[rt * 2 + 1].right - segTree[rt * 2 + 1].left + 1);
42         segTree[rt].addMark = 0;    //标记清空
43     }
44 }
45 
46 void update(int x, int y, int w, int l, int r, int rt)
47 {
48     if(x > r || y < l)
49     {
50         return;
51     }
52     if(x <= l && y >= r)
53     {
54         segTree[rt].addMark = w ;
55         segTree[rt].val = w * (segTree[rt].right - segTree[rt].left + 1) ;
56         return;
57     }
58     pushDown(rt);
59     int mid = (l + r) / 2;
60     if(x <= mid)
61         update(x, y, w, l, mid, rt * 2);
62     if(y > mid)
63         update(x, y, w, mid + 1, r, rt * 2 + 1);
64     pushUp(rt);
65 }
66 
67 int main()
68 {
69     ios::sync_with_stdio(false);
70     int t, n, q, x, y, w, ca = 1;
71     cin >> t;
72     while(t--)
73     {
74         cin >> n >> q;
75         build(1, n, 1);
76         while(q--)
77         {
78             cin >> x >> y >> w;
79             update(x, y, w, 1, n, 1);
80         }
81         cout << "Case " << ca << ": The total value of the hook is " << segTree[1].val << "." << endl;
82         ca++;
83     }
84     return 0;
85 }

体会:

  熟悉一下线段树区间更新操作的写法

原文地址:https://www.cnblogs.com/friend-A/p/9401223.html