hihocoder1078 线段树的区间修改

思路:

线段树区间更新。注意这里是把一个区间的所有数全部赋值为一个新的值。

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100005;
 4 int tree[N << 2], lazy[N << 2], a[N], n, q;
 5 
 6 void build(int num, int l, int r)
 7 {
 8     if (l == r) { tree[num] = a[l]; return; }
 9     int m = l + r >> 1;
10     build(num << 1, l, m);
11     build(num << 1 | 1, m + 1, r);
12     tree[num] = tree[num << 1] + tree[num << 1 | 1];
13 }
14 
15 void pushdown(int num, int cl, int cr)
16 {
17     if (!lazy[num]) return;
18     tree[num << 1] = lazy[num] * cl;
19     tree[num << 1 | 1] = lazy[num] * cr;
20     lazy[num << 1] = lazy[num];
21     lazy[num << 1 | 1] = lazy[num];
22     lazy[num] = 0;
23 }
24 
25 void update(int num, int l, int r, int x, int y, int p)
26 {
27     if (x <= l && y >= r) { tree[num] = (r - l + 1) * p; lazy[num] = p; return; }
28     int m = l + r >> 1;
29     pushdown(num, m - l + 1, r - m);
30     if (x <= m) update(num << 1, l, m, x, y, p);
31     if (y >= m + 1) update(num << 1 | 1, m + 1, r, x, y, p);
32     tree[num] = tree[num << 1] + tree[num << 1 | 1];
33 }
34 
35 int query(int num, int l, int r, int x, int y)
36 {
37     if (x <= l && y >= r) return tree[num];
38     int m = l + r >> 1;
39     pushdown(num, m - l + 1, r - m);
40     int ans = 0;
41     if (x <= m) ans += query(num << 1, l, m, x, y);
42     if (y >= m + 1) ans += query(num << 1 | 1, m + 1, r, x, y);
43     return ans;
44 }
45 
46 int main()
47 {
48     ios::sync_with_stdio(false);
49     cin >> n;
50     for (int i = 1; i <= n; i++) cin >> a[i];
51     build(1, 1, n);
52     cin >> q;
53     int x, y, t, p;
54     for (int i = 1; i <= q; i++)
55     {
56         cin >> t;
57         if (t == 0)
58         {
59             cin >> x >> y;
60             cout << query(1, 1, n, x, y) << endl;
61         }
62         else
63         {
64             cin >> x >> y >> p;
65             update(1, 1, n, x, y, p);
66         }
67     }
68     return 0;
69 }

猜你喜欢

转载自www.cnblogs.com/wangyiming/p/9167053.html