@@ -32,26 +32,26 @@ struct seg_tree {
3232
3333// what: iterative segment tree for point update and range sum.
3434// time: build O(n), update/query O(log n); memory: O(n)
35- // constraint: 0 -indexed [l, r) .
35+ // constraint: 1 -indexed [1, n]; a[0] unused .
3636// usage: seg_tree_it st; st.build(a); st.set(p, v); st.query(l, r);
37- struct seg_tree_it { // 0 -indexed
37+ struct seg_tree_it { // 1 -indexed
3838 int n;
3939 vector<ll> t;
4040 void build (const vector<ll> &a) {
41- // goal: build tree from 0 -indexed array.
42- n = sz (a);
41+ // goal: build tree from 1 -indexed array.
42+ n = sz (a) - 1 ;
4343 t.assign (2 * n, 0 );
44- for (int i = 0 ; i < n; i++) t[n + i] = a[i];
44+ for (int i = 1 ; i <= n; i++) t[n + i - 1 ] = a[i];
4545 for (int i = n - 1 ; i >= 1 ; i--) t[i] = t[i << 1 ] + t[i << 1 | 1 ];
4646 }
4747 void set (int p, ll val) {
4848 // goal: set a[p] = val.
49- for (t[p += n] = val; p > 1 ; p >>= 1 ) t[p >> 1 ] = t[p] + t[p ^ 1 ];
49+ for (t[p += n - 1 ] = val; p > 1 ; p >>= 1 ) t[p >> 1 ] = t[p] + t[p ^ 1 ];
5050 }
5151 ll query (int l, int r) const {
52- // result: sum on [l, r) .
52+ // result: sum on [l, r] .
5353 ll ret = 0 ;
54- for (l += n, r += n; l < r; l >>= 1 , r >>= 1 ) {
54+ for (l += n - 1 , r += n; l < r; l >>= 1 , r >>= 1 ) {
5555 if (l & 1 ) ret += t[l++];
5656 if (r & 1 ) ret += t[--r];
5757 }
@@ -183,18 +183,18 @@ struct seg_sparse {
183183
184184// what: 2D point updates with rectangle sum queries on a square grid.
185185// time: build O(n^2), update/query O(log^2 n); memory: O(n^2)
186- // constraint: 0 -indexed square n x n .
186+ // constraint: 1 -indexed square [1..n] x [1..n]; a[0][*], a[*][0] unused .
187187// usage: seg_2d st; st.build(a); st.set(x, y, v); st.query(x1, x2, y1, y2);
188- struct seg_2d { // 0 -indexed
188+ struct seg_2d { // 1 -indexed
189189 int n;
190190 vector<vector<ll>> t;
191191 void build (const vector<vector<ll>> &a) {
192192 // goal: build 2D tree from initial grid.
193- n = sz (a);
193+ n = sz (a) - 1 ;
194194 t.assign (2 * n, vector<ll>(2 * n, 0 ));
195- for (int i = 0 ; i < n; i++)
196- for (int j = 0 ; j < n; j++)
197- t[i + n][j + n] = a[i][j];
195+ for (int i = 1 ; i <= n; i++)
196+ for (int j = 1 ; j <= n; j++)
197+ t[i + n - 1 ][j + n - 1 ] = a[i][j];
198198 for (int i = n; i < 2 * n; i++)
199199 for (int j = n - 1 ; j > 0 ; j--)
200200 t[i][j] = t[i][j << 1 ] + t[i][j << 1 | 1 ];
@@ -204,6 +204,7 @@ struct seg_2d { // 0-indexed
204204 }
205205 void set (int x, int y, ll val) {
206206 // goal: set a[x][y] = val.
207+ x--, y--;
207208 t[x + n][y + n] = val;
208209 for (int j = y + n; j > 1 ; j >>= 1 )
209210 t[x + n][j >> 1 ] = t[x + n][j] + t[x + n][j ^ 1 ];
@@ -222,6 +223,7 @@ struct seg_2d { // 0-indexed
222223 }
223224 ll query (int x1, int x2, int y1, int y2) const {
224225 // result: sum on rectangle [x1..x2] x [y1..y2].
226+ x1--, x2--, y1--, y2--;
225227 ll ret = 0 ;
226228 for (x1 += n, x2 += n + 1 ; x1 < x2; x1 >>= 1 , x2 >>= 1 ) {
227229 if (x1 & 1 ) ret += qry1d (x1++, y1, y2);
@@ -233,21 +235,21 @@ struct seg_2d { // 0-indexed
233235
234236// what: 2D segment tree with coordinate compression for sparse updates/queries.
235237// time: prep O(q log q), update/query O(log^2 n); memory: O(q log q)
236- // constraint: call mark_set/mark_qry first, then prep, then set/query.
238+ // constraint: x is 1-indexed [1..n]; y is coordinate value; call mark_set/mark_qry first, then prep, then set/query.
237239// usage: seg2d_comp st(n); st.mark_set(x, y); st.mark_qry(x1, x2, y1, y2); st.prep(); st.set(x, y, v); st.query(x1, x2, y1, y2);
238- struct seg2d_comp { // 0 -indexed
240+ struct seg2d_comp { // x: 1 -indexed
239241 int n;
240242 vector<vector<ll>> a;
241243 vector<vector<int >> used;
242244 unordered_map<ll, ll> mp;
243245 seg2d_comp (int n) : n(n), a(2 * n), used(2 * n) {}
244246 void mark_set (int x, int y) {
245247 // goal: record y-coordinates that will be updated.
246- for (x += n; x >= 1 ; x >>= 1 ) used[x].push_back (y);
248+ for (x += n - 1 ; x >= 1 ; x >>= 1 ) used[x].push_back (y);
247249 }
248250 void mark_qry (int x1, int x2, int y1, int y2) {
249251 // goal: record y-coordinates needed for queries.
250- for (x1 += n, x2 += n + 1 ; x1 < x2; x1 >>= 1 , x2 >>= 1 ) {
252+ for (x1 += n - 1 , x2 += n; x1 < x2; x1 >>= 1 , x2 >>= 1 ) {
251253 if (x1 & 1 ) {
252254 used[x1].push_back (y1);
253255 used[x1++].push_back (y2);
@@ -274,7 +276,7 @@ struct seg2d_comp { // 0-indexed
274276 ll k = (ll)x << 32 | (unsigned )y;
275277 ll d = v - mp[k];
276278 mp[k] = v;
277- for (x += n; x >= 1 ; x >>= 1 ) {
279+ for (x += n - 1 ; x >= 1 ; x >>= 1 ) {
278280 int i = lower_bound (all (used[x]), y) - used[x].begin () + sz (used[x]);
279281 for (a[x][i] += d; i > 1 ; i >>= 1 )
280282 a[x][i >> 1 ] = a[x][i] + a[x][i ^ 1 ];
@@ -294,7 +296,7 @@ struct seg2d_comp { // 0-indexed
294296 ll query (int x1, int x2, int y1, int y2) const {
295297 // result: sum on rectangle [x1..x2] x [y1..y2].
296298 ll ret = 0 ;
297- for (x1 += n, x2 += n + 1 ; x1 < x2; x1 >>= 1 , x2 >>= 1 ) {
299+ for (x1 += n - 1 , x2 += n; x1 < x2; x1 >>= 1 , x2 >>= 1 ) {
298300 if (x1 & 1 ) ret += qry1d (x1++, y1, y2);
299301 if (x2 & 1 ) ret += qry1d (--x2, y1, y2);
300302 }
0 commit comments