单点修改+区间查询的分块,主要问题查询和确定左右边界上
#include <bits/stdc++.h> #define LOCAL using namespace std; #define vec vector #define ll long long #define ld long double #define sza(x) ((int)x.size()) #define all(a) (a).begin(), (a).end() const int MAX_N = 1e5 + 5; const ll MOD = 1e9 + 7; const ll INF = 1e9; const ld EPS = 1e-9; int n, m; vec<int> v; vec<int> belong(1000010); int sum[1010]; int block; int cnt; int query(int a, int b){ if(belong[a] == belong[b]){ int res = 0; for(int i = a; i <= b; i ++) res += v[i]; return res; } int res = 0; int R = (belong[a] + 1) * block - 1; int L = belong[b] * block; for(int i = a; i <= R; i ++) res += v[i]; for(int i = L; i <= b; i ++) res += v[i]; for(int i = belong[a] + 1; i <= belong[b] - 1; i ++) res += sum[i]; return res; } void add(int pos, int x){ v[pos] += x; sum[belong[pos]] += x; } void solve() { while(cin >> n >> m){ memset(sum, 0, sizeof sum); v.clear(); for(int i = 0; i < n; i ++){ int t; cin >> t; v.push_back(t); } block = sqrt(n); // 每块的大小 cnt = n / block; if(n % block) cnt ++; for(int i = 0; i < cnt; i ++){ int l = i * block; int r = min((i + 1) * block - 1, n - 1); for(int j = l; j <= r; j ++){ belong[j] = i; sum[i] += v[j]; } } while(m --){ string s; int a, b; cin >> s >> a >> b; if(s == "QUERY") cout << query(a - 1, b - 1) << endl; else add(a - 1, b); // for(int i = 0; i < n; i ++) cout << v[i] << ' '; // cout << endl; } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int tc = 1; // cin >> tc; for (int t = 1; t <= tc; t++) { // cout << "Case #" << t << ": "; solve(); } }