The tree array can only implement the function of section modification and interval query, instead of the line tree without lazy tag, and the code quantity and constant are small .
First define an array of int c[n]; and empty memset (c, 0, sizeof C);
1, Single point modification: c[x] + = y; The corresponding function is the change (x, y);
2. Prefix and: the corresponding function is int sum (x)
The complexity of both operations is O (LOGN)
The template is as follows:
int c[n], MAXN; inline int lowbit (int x) {return x& (-X);} void change (int i, int x)//i point increment is x {while (I <= maxn) { C[i] + = x; i + = Lowbit (i); } } int sum (int x) {//Interval sum [1,x] int ans = 0; for (int i = x; I >= 1; I-= Lowbit (i)) ans + = c[i]; return ans; }
How to use a tree-like array for interval operation
First, define two tree arrays X, Y
Now we need an array of int a[n]; Interval operation: [L, R] + = val is for i:l to R a[i] + = val;
Then define an int size = r-l+1, which is the interval length
The corresponding modification is
1, x[l] + = val; X[r+1]-= Val;
2, y[l] + =-1 * val * (L-1); Y[r+1] + = val * R;
The corresponding query is
When we sum the operation in the tree array is ans = x.sum (k) * k + y.sum (k)
Category discussion k respectively in [1,l-1], [L, R], [r+1, +]
1, K[1,l-1]
Obviously x.sum (k) = = 0 and y.sum (k) = = 0-ans = x.sum (k) *k + y.sum (k) = 0*i+0 = 0 The result is in accordance with the actual.
2, K[l, R]
X.sum (k) * k = x[l] * k = val * k, y.sum (k) = y[l] = 1 * val * (L-1)
Ans = val * k-val * (L-1) = Val * (k-(L-1));
3, K[r+1,]
X.sum (k) * k = (X[l] + x[r]) * k = 0 * k = 0;
Y.sum (k) = Y[l] + y[r] =-val * (L-1) + val * R = val * (r-l+1) = val * size
X.sum (k) * k + y.sum (k) = val * size
Proof is complete.
The two tree arrays in the following template c[0], c[1] correspond to the above X, Y
Interval modification: Add (L, R, Val)
Prefix and Get_pre (R) for int a[n]
Interval query: Get (L,R)
const int N = 4e5 + 100;template<class t>struct tree{t c[2][n];int maxn;void init (int x) {maxn = x+10; memset (c, 0, S Izeof c);} inline int lowbit (int x) {return x&-x;} T sum (t *b, int x) {T ans = 0;if (x = = 0) ans = b[0];while (x) ans + = b[x], X-= Lowbit (x); return ans; void Change (t *b, int x, t value) {if (x = = 0) b[x] + = value, X++;while (x <= maxn) b[x] + = value, x + = Lowbit (x);} T get_pre (int r) {return sum (c[0], R) * r + sum (c[1], r);} void Add (int l, int r, T value) {//Interval weighted change (c[0], L, value); Change (c[0], R + 1,-value); Change (c[1], L, Value * (-L + 1)) ; Change (c[1], R + 1, value * r);} T get (int l, int r) {//Interval sum return Get_pre (R)-Get_pre (L-1);}}; Tree<ll> Tree;
Well, back to the point, let's talk about the test instructions of the problem:
Test instructions: A two-dimensional planar w operation for a given n*m
int Mp[n][m] = {0};
1, 0 (x1,y1) (x2,y2) value
For i:x1 to X2
For J:y1 to Y2
MP[I][J] + = value;
2, 1 (x1, y1) (x2 y2)
ANS1 = total number of ordinate between y1,y2
ANS2 = The total number of horizontal axis not x1,x2 between
Puts (ANS1-ANS2);
The code is as follows:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace Std;typedef Long long ll;const int n = 4e6+10;int n, m, w;template<class t> struct tree{ll c[2][n]; int MAXN; void init (int x) {maxn = x+10; memset (c, 0, sizeof C); } inline int lowbit (int x) {return x&-x;} ll sum (ll *b, int x) {ll ans = 0; if (x = = 0) ans = b[0]; while (x) ans + = b[x], X-= Lowbit (x); return ans; } void Change (ll *b, int x, ll value) {if (x = = 0) b[x] + = value, x + +; while (x <= maxn) b[x] + = value, x + = Lowbit (x); } ll Get_pre (int r) {return sum (c[0], R) * r + sum (c[1], R); } void Add (int l, int r, ll value) {change (c[0], L, value); Change (C[0], R + 1,-value); Change (c[1], L, Value * (-L + 1)); Change (C[1], R + 1, value * r); } ll get (int l, int r) {return Get_pre(r)-Get_pre (L-1); } }; Tree<ll> x, y; int main () {scanf ("%d%d%d", &n, &m, &w); X.init (n); Y.init (m); int tmp;ll all = 0;while (w--) {scanf ("%d", &t MP); int x1, x2, y1, y2, v;if (tmp = = 0) {scanf ("%d%d%d%d%d", &x1, &y1, &x2, &y2, &v); all + = v * (x2-x1+1 ) * (y2-y1+1); X.add (x1, x2, V * (y2-y1 + 1)); Y.add (y1, y2, V * (x2-x1 + 1));} if (tmp = = 1) {scanf ("%d%d%d%d", &x1, &y1, &x2, &y2);p rintf ("%i64d\n", Y.get (1, y2)-y.get (1, y1-1)-(All -X.get (1, x2) + x.get (1, x1-1));}} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Codeforces 390E Inna and Large Sweet Matrix (tree array change segment)