线段树区间修改

这里给一个区间修改,求区间和的代码,也可以用到求区间最值,乘积等问题。 

 

这个想法是sum[]和lazy[]同时修改。以前我写的是lazy[now]往下传给now << 1和now << 1 | 1的时候再修改sum[],这个写法的逻辑不是很好,推荐下面的这个思路。

 

 1 #include<cstdio>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5 + 5;
 5 
 6 int l[maxn << 2], r[maxn << 2], lazy[maxn << 2];
 7 ll sum[maxn << 2];
 8 void build(int L, int R, int now)
 9 {
10     l[now] = L; r[now] = R;
11     if(L == R) {scanf("%lld", &sum[now]); return;}
12     int mid = (L + R) >> 1;
13     build(L, mid, now << 1);
14     build(mid + 1, R, now << 1 | 1);
15     sum[now] = sum[now << 1] + sum[now << 1 | 1];
16 }
17 void pushdown(int now)
18 {
19     if(lazy[now])
20     {
21         lazy[now << 1] += lazy[now];
22         lazy[now << 1 | 1] += lazy[now];
23         sum[now << 1] += (r[now << 1] - l[now << 1] + 1) * lazy[now];
24         sum[now << 1 | 1] += (r[now << 1 | 1] - l[now << 1 | 1] + 1) * lazy[now];
25         lazy[now] = 0;
26     }
27 }
28 void update(int L, int R, int now, int d)
29 {
30     if(L == l[now] && R == r[now])
31     {
32         sum[now] += (r[now] - l[now] + 1) * d;
33         lazy[now] += d;
34         return;
35     }
36     pushdown(now);    
37     int mid = (l[now] + r[now]) >> 1;
38     if(R <= mid) update(L, R, now << 1, d);
39     else if(L > mid) update(L, R, now << 1 | 1, d);
40     else {update(L, mid, now << 1, d); update(mid + 1, R, now << 1 | 1, d);}
41     sum[now] = sum[now << 1] + sum[now << 1 | 1];
42 }
43 ll query(int L, int R, int now)
44 {
45     if(L == l[now] && R == r[now]) return sum[now];
46     pushdown(now);
47     int mid = (l[now] + r[now]) >> 1;
48     if(R <= mid) return query(L, R, now << 1);
49     else if(L > mid) return query(L, R, now << 1 | 1);
50     else return query(L, mid, now << 1) + query(mid + 1, R, now << 1 | 1);
51 }
52 
53 int main()
54 {
55     int n, m; scanf("%d%d", &n, &m);
56     build(1, n, 1);
57     for(int i = 1; i <= m; ++i)
58     {
59         int d; scanf("%d", &d);
60         if(d == 1) 
61         {
62             int a, b, c; scanf("%d%d%d", &a, &b, &c);
63             update(a, b, 1, c); 
64         }
65         else
66         {
67             int a, b; scanf("%d%d", &a, &b);
68             printf("%lld\n", query(a, b, 1));
69         }
70     }
71 }

 

posted @ 2018-05-12 11:21  mrclr  阅读(546)  评论(1编辑  收藏  举报