题目描述
这是一道模板题。
给定数列 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 6数据范围与提示
对于所有数据,1≤n,q≤1e6, ∣ai∣≤1e6, 1≤l≤r≤n,∣x∣≤1e6。
线段树版本码量明显比树状数组大点
AC代码:
#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> #include <numeric> #define rep(i,j) for(int i = 1;i <= j;i++) #define gao(x) cerr << #x << "->" << x << endl #define gen(x) x##_ typedef long long ll; typedef double db; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const double eps = 1e-6; int n, q; int a[1000010]; struct node { int l, r; long long s; }tree[4 * 1000010]; void push_up(int id) { tree[id].s = tree[id << 1].s + tree[id << 1 | 1].s; return; } void build(int id, int l, int r) { tree[id].l = l; tree[id].r = r; if (l == r) { tree[id].s = a[l]; return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); push_up(id); return; } void update(int id, int x, int k) { int L = tree[id].l, R = tree[id].r; if (L == R) { tree[id].s += k; return; } if (x <= tree[id << 1].r) { update(id << 1, x, k); } else { update(id << 1 | 1, x, k); } push_up(id); } long long query(int id, int l, int r) { int L = tree[id].l, R = tree[id].r; long long ans = 0; if (R < L || L > r) { return 0; } if (l <= L && R <= r) { return tree[id].s; } if (tree[id << 1].r >= l) { ans += query(id << 1, l, r); } if (tree[id << 1 | 1].l <= r) { ans += query(id << 1 | 1, l, r); } return ans; } void solve() { std::cin >> n >> q; for (int i = 1; i <= n; i++) { std::cin >> a[i]; } build(1, 1, n); while (q--) { int k, x, y; std::cin >> k >> x >> y; if (k == 1) { update(1, x, y); } else { std::cout << query(1, x, y) << std::endl; } } return; } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); solve(); return 0; }
线段树模板
最新推荐文章于 2023-01-19 10:34:40 发布