树状数组专题
树状数组相较于线段树好写,但是局限于查询区间和,没啥功能
落谷3374
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int b[1000];
const int N = 500005;
int n, m;
inline int lowbit(int x) {
return x & (-x);
}
ll count(int p) {
if (p == 0) return 0;
return count(p - lowbit(p)) + b[p];
}
void add(int p,int x) {
while (p <=n) {
b[p] += x;
p += lowbit(p);
}
}
int main() {
cin >> n >> m;
int a;
for (int i = 1; i <= n; i++) {
cin >> a;
add(i, a);
}
int x, y;
while (m--) {
cin >> a >> x >> y;
if (a == 1) {
add(x, y);
}
else {
cout << count(y) - count(x - 1) << endl;
}
}
return 0;
}
落谷 3368
这个题目不同于上面这个题,我们需要,数组中装的不再是和,而是差分
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 500005;
int a[N];
int n, m;
inline int lowbit(int x) {
return x & (-x);
}
void add(int x, int p) {
while (x <= n) {
a[x] += p;
x += lowbit(x);
}
}
ll count(int x) {
if (x == 0) return 0;
return count(x - lowbit(x)) + a[x];
}
int main() {
cin >> n >> m;
int b;
int last = 0;
for (int i = 1; i <= n; i++) {
cin >> b;
add(i, b-last); // 构造一个前缀差分
last = b;
}
int c, d, e;
while (m--) {
cin >> b;
if (b == 1) {
cin >> c >> d >> e;
add(c, e);
add(d + 1, -e);
}
else {
cin >> c;
cout << count(c) << endl;
}
}
return 0;
}
luogu5057
如果这个用普通的前缀和的话,会tle两个点
这个题目的关键就是
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
int n, m;
const int N = 500005;
int a[N];
inline int lowbit(int x) {
return x & (-x);
}
void add(int x, int p) {
while (x <= n) {
a[x] += p;
x += lowbit(x);
}
}
int count(int x) {
if (x == 0) return 0;
return count(x - lowbit(x)) + a[x];
}
int main() {
cin >> n >> m;
int t, b, c;
while (m--) {
cin >> t;
if (t == 1) {
cin >> b >> c;
add(b, 1);
add(c+1, 1);
}
else {
cin >> b;
int ans = 0;
cout << count(b) % 2 << endl;
}
}
return 0;
}
原文地址:https://blog.csdn.net/wniuniu_/article/details/139105249
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!