树状数组 1 :单点修改,区间查询 Gym - 237040B
这是一道模板题。
给定数列 a[1],a[2],…,a[n]a[1],a[2],…,a[n],你需要依次进行 qq 个操作,操作有两类:
- "1 i x":给定 i,xi,x,将 a[i]a[i] 加上 xx;
- "2 l r":给定 l,rl,r,求 ∑ri=la[i]∑i=lra[i] 的值(换言之,求 a[l]+a[l+1]+⋯+a[r]a[l]+a[l+1]+⋯+a[r] 的值)。
Input
第一行包含 22 个正整数 n,qn,q,表示数列长度和询问个数。保证 1≤n,q≤1061≤n,q≤106。 第二行 nn 个整数 a[1],a[2],…,a[n]a[1],a[2],…,a[n],表示初始数列。保证 |a[i]|≤106|a[i]|≤106。
接下来 qq 行,每行一个操作,为以下两种之一:
- "1 i x":给定 i,xi,x,将 a[i]a[i] 加上 xx;
- "2 l r":给定 l,rl,r,求 ∑ri=la[i]∑i=lra[i] 的值。
保证 1≤l≤r≤n,1≤l≤r≤n, |x|≤106|x|≤106。
Output
对于每个 "2 l r" 操作输出一行,每行有一个整数,表示所求的结果。
Example
Input
3 2 1 2 3 1 2 0 2 1 3
Output
6
Note
对于所有数据,1≤n,q≤106,1≤n,q≤106, |a[i]|≤106|a[i]|≤106, 1≤l≤r≤n,1≤l≤r≤n, |x|≤106|x|≤106。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5+10; ll Case, n, m, i, j; ll a[5000010]; inline void add(ll x, ll y) { for (ll i = x; i <= n; i += i & (-i)) { a[i] += y; } } inline ll getsum(ll x) { ll sum = 0; for (ll i = x; i; i -= i & (-i)) { sum += a[i]; } return sum; } int main() { scanf("%lld%lld", &n, &m); for (i = 1; i <= n; i++) { ll x; scanf("%lld", &x); add(i, x); } for (i = 1; i <= m; i++) { ll type; scanf("%lld", &type); if (type == 1) { ll x, k; scanf("%lld%lld", &x, &k); add(x, k); }else{ ll x, y; scanf("%lld%lld", &x, &y); printf("%lld\n", getsum(y) - getsum(x - 1)); } } }