题目链接:http://codeforces.com/contest/444/problem/C

给定一个长度为.有两种操作:

  1. 将区间|.
  2. 询问区间]的权值和.

.

感觉这是一个比较好的考察线段树区间更新的性质。

当区间的a[i]一样时,区间更新即可,这是剪枝。

注意,lazy标记存的是增量。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int N = 1e5 + 5;
 5 struct SegTree {
 6     LL l, r, Min, Max;
 7     LL val, lazy;
 8 }T[N << 2];
 9 
10 LL Abs(LL a) {
11     return a < 0 ? -a : a;
12 }
13 
14 void pushup(int p) {
15     T[p].Min = min(T[p << 1].Min, T[(p << 1)|1].Min);
16     T[p].Max = max(T[p << 1].Max, T[(p << 1)|1].Max);
17     T[p].val = T[p << 1].val + T[(p << 1)|1].val;
18 }
19 
20 void pushdown(int p) {
21     if(T[p].l == T[p].r) {
22         return ;
23     } else if(T[p].lazy) {
24         T[p << 1].lazy += T[p].lazy;
25         T[(p << 1)|1].lazy += T[p].lazy;
26         T[p << 1].val += T[p].lazy*(LL)(T[p << 1].r - T[p << 1].l + 1);
27         T[(p << 1)|1].val += T[p].lazy*(LL)(T[(p << 1)|1].r - T[(p << 1)|1].l + 1);
28         T[p << 1].Min = T[p << 1].Max = T[(p << 1)|1].Max = T[(p << 1)|1].Min = T[p].Min;
29         T[p].lazy = 0;
30     }
31 }
32 
33 void build(int p, int l, int r) {
34     int mid = (l + r) >> 1;
35     T[p].l = l, T[p].r = r, T[p].lazy = 0;
36     if(l == r) {
37         T[p].Max = l, T[p].Min = l;
38         T[p].val = 0;   
39         return ;
40     }
41     build(p << 1, l, mid);
42     build((p << 1)|1, mid + 1, r);
43     pushup(p);
44 }
45 
46 void update(int p, int l, int r, LL add) {
47     int mid = (T[p].l + T[p].r) >> 1;
48     pushdown(p);
49     if(l == T[p].l && T[p].r == r && T[p].Min == T[p].Max) {
50         T[p].val += (LL)Abs(add - T[p].Min)*(LL)(r - l + 1);
51         T[p].lazy += Abs(add - T[p].Max);
52         T[p].Max = T[p].Min = add;
53         return ;
54     }
55     if(r <= mid) {
56         update(p << 1, l, r, add);
57     } else if(l > mid) {
58         update((p << 1)|1, l, r, add);
59     } else {
60         update(p << 1, l, mid, add);
61         update((p << 1)|1, mid + 1, r, add);
62     }
63     pushup(p);
64 }
65 
66 LL query(int p, int l, int r) {
67     int mid = (T[p].l + T[p].r) >> 1;
68     pushdown(p);
69     if(l == T[p].l && T[p].r == r) {
70         return T[p].val;
71     }
72     if(r <= mid) {
73         return query(p << 1, l, r);
74     } else if(l > mid) {
75         return query((p << 1)|1, l, r);
76     } else {
77         return query(p << 1, l, mid) + query((p << 1)|1, mid + 1, r);
78     }
79     pushup(p);
80 }
81 
82 int main()
83 {
84     int n, m, l, r, c;
85     LL add;
86     scanf("%d %d", &n, &m);
87     build(1, 1, n);
88     while(m--) {
89         scanf("%d %d %d", &c, &l, &r);
90         if(c == 1) {
91             scanf("%lld", &add);
92             update(1, l, r, add);
93         } else {
94             printf("%lld\n", query(1, l, r));
95         }
96     }
97     return 0;
98 }

 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-02-20
  • 2021-07-30
  • 2021-09-02
  • 2021-10-03
  • 2022-02-12
  • 2021-08-22
猜你喜欢
  • 2021-08-13
  • 2022-12-23
  • 2021-07-12
  • 2021-07-02
  • 2021-10-27
  • 2021-08-05
  • 2021-11-04
相关资源
相似解决方案