单点修改+区间求和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<bits/stdc++.h>
#define endl '\n'
using i64 = long long;
using namespace std;
signed main(){
std::ios::sync_with_stdio(false);cin.tie(0);
int n, m;
cin >> n >> m;
vector<i64> a(n + 1);
auto add = [&](int x, i64 k) -> void
{
for (int i = x; i <= n; i += i & (-i))
a[i] += k;
};
auto query = [&](int x) -> i64
{
i64 res = 0;
for (int i = x; i; i -= i & (-i))
res += a[i];
return res;
};
for (int i = 1; i <= n; i++){
int x;
cin >> x;
add(i, x);
}
while (m--){
int opt;
cin >> opt;
if (opt == 1){
int x;
i64 k;
cin >> x >> k;
add(x, k);
}
else{
int x, y;
i64 ans;
cin >> x >> y;
ans = query(y) - query(x - 1);
cout << ans << endl;
}
}
return 0;
}

区间修改+单点查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include<bits/stdc++.h>
#define endl '\n'
using i64 = long long;
using namespace std;
signed main(){
std::ios::sync_with_stdio(false);cin.tie(0);
int n, m;
cin >> n >> m;
vector<i64> a(n + 1), diff(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
auto add = [&](int x, i64 k) -> void
{
for (int i = x; i <= n; i += i & (-i))
diff[i] += k;
};
auto query = [&](int x) -> i64
{
i64 res = 0;
for (int i = x; i; i -= i & (-i))
res += diff[i];
return res;
};
while (m--){
int opt;
cin >> opt;
if (opt == 1){
int x, y;
i64 k;
cin >> x >> y >> k;
add(x, k), add(y + 1, -k);
}
else{
int x;
i64 ans;
cin >> x;
ans = a[x] + query(x);
cout << ans << endl;
}
}
return 0;
}

区间修改+区间查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <bits/stdc++.h>
#define endl '\n'
using i64 = long long;
using namespace std;
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
int n, q;
cin >> n >> q;
vector<i64> a(n + 1), b(n + 1), diff(n + 1), t(n + 1);
for (int i = 1; i <= n; i++){
cin >> a[i];
b[i] = a[i] - a[i - 1];
}
auto add1 = [&](int x, i64 k) -> void
{
for (int i = x; i <= n; i += i & (-i)){
diff[i] += k;
t[i] += k * x;
}
};
auto add2 = [&](int l, int r, i64 x) -> void
{
add1(l, x), add1(r + 1, -x);
};
auto query1 = [&](int x) -> i64
{
i64 res = 0;
for (int i = x; i; i -= i & (-i))
res += (x + 1) * diff[i] - t[i];
return res;
};
auto query2 = [&](int l, int r) -> i64
{
return query1(r) - query1(l - 1);
};
for (int i = 1; i <= n; i++)
add1(i, b[i]);
while (q--){
int opt;
cin >> opt;
if (opt == 1){
int l, r;
i64 x;
cin >> l >> r >> x;
add2(l, r, x);
}
else{
int l, r;
cin >> l >> r;
cout << query2(l, r) << endl;
}
}
return 0;
}