Here is an introduction to how to use a tree array for interval modification and interval queries
Instead of a line tree that does not require lazy tags, the code size and the constant are small
First you need to learn the tree array, if not the following first to explain the black box use the posture of the tree array first define an array 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
Certificate of Completion
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;
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
A detailed description of the modified section of the tree array