思路:
线段树区间更新。注意这里是把一个区间的所有数全部赋值为一个新的值。
实现:
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 }