树状数组 1 :单点修改,区间查询
题目描述
这是一道模板题。
给定数列 a1,a2,…,an,你需要依次进行 q 个操作,操作有两类:
1 i x
:给定 i,x,将 ai 加上 x;2 l r
:给定 l,r,求∑i=lrai 的值(换言之,求al+al+1+⋯+ar 的值)。输入格式
第一行包含 2 个正整数 n,q,表示数列长度和询问个数。保证1≤n,q≤1e6。
第二行 n 个整数 a1,a2,…,an,表示初始数列。保证 ∣ai∣≤1e6。
接下来 q 行,每行一个操作,为以下两种之一:
1 i x
:给定 i,x,将 a[i] 加上 x;2 l r
:给定 l,r,求 ∑i=lrai 的值。保证 1≤l≤r≤n, ∣x∣≤1e6。
输出格式
对于每个
2 l r
操作输出一行,每行有一个整数,表示所求的结果。样例
Input Output 3 2 1 2 3 1 2 0 2 1 3 6AC代码:
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <list> #include <set> #include <istream> #include <sstream> #include <iomanip> typedef long long ll; typedef double db; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const double eps = 1e-6; using namespace std; int n,q; int a[1000010]; long long tree[1000010]; int lowbit(int x){ return x & -x; } void add(int x,int v){ while(x <= n){ tree[x] += v; x += lowbit(x); } } long long get(int x){ long long cnt = 0; while(x){ cnt += tree[x]; x -= lowbit(x); } return cnt; } void solve(){ cin >> n >> q; for(int i = 1;i <= n;i++){ cin >> a[i]; add(i,a[i]); } while(q--){ int id,x,y; cin >> id >> x >> y; if(id == 1){ add(x,y); } if(id == 2){ cout << get(y) - get(x - 1) << endl; } } return ; } int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); solve(); return 0; } /* */
树状数组 2 :区间修改,单点查询:
题目描述
这是一道模板题。
给定数列 a[1],a[2],…,a[n],你需要依次进行 q 个操作,操作有两类:
1 l r x
:给定 l,r,x,对于所有i∈[l,r],将 a[i] 加上 x(换言之,将 a[l],a[l+1],…,a[r] 分别加上 x);2 i
:给定 i,求 a[i] 的值。输入格式
第一行包含 2 个正整数 n,q,表示数列长度和询问个数。保证 1≤n,q≤1e6。
第二行 n 个整数a[1],a[2],…,a[n],表示初始数列。保证a[i]∣≤1e6。
接下来 q 行,每行一个操作,为以下两种之一:
1 l r x
:对于所有i∈[l,r],将 a[i] 加上 x;2 i
:给定 i,求 a[i] 的值。保证1≤l≤r≤n,∣x∣≤1e6。
输出格式
对于每个
2 i
操作,输出一行,每行有一个整数,表示所求的结果。样例
Input Output 3 2 1 2 3 1 1 3 0 2 2 2AC代码:
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <list> #include <set> #include <istream> #include <sstream> #include <iomanip> typedef long long ll; typedef double db; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const double eps = 1e-6; using namespace std; int n,q; int a[1000010],b[1000010]; long long tree[1000010]; int lowbit(int x){ return x & -x; } void add(int x,int v){ while(x <= n){ tree[x] += v; x += lowbit(x); } } long long get(int x){ long long cnt = 0; while(x){ cnt += tree[x]; x -= lowbit(x); } return cnt; } void solve(){ cin >> n >> q; for(int i = 1;i <= n;i++){ cin >> a[i]; if(i == 1){ b[1] = a[1]; } else{ b[i] = a[i] - a[i - 1]; } } for(int i = 1;i <= n;i++){ tree[i] += b[i]; long long j = i + lowbit(i); if(j <= n){ tree[j] += tree[i]; } } while(q--){ int id,l,r,x; cin >> id; if(id == 1){ cin >> l >> r >> x; add(l,x); add(r + 1,-x); } if(id == 2){ cin >> l; cout << get(l) << endl; } } return ; } int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); solve(); return 0; } /* */
难点-树状数组
最新推荐文章于 2023-09-18 03:56:34 发布