emmmmm, before we learn Fenwick tree, we should know lowbit (n) operation, lowbit (n) non-negative integer value of n is defined configuration of "all 1's and 0 behind the least significant bit" in a binary, n = e.g. 10 is expressed as binary \ ((1010) 2 \) , then \ (lowbit (n-) = 2 = (10) 2 \) , apparent
\[lowbit(n) = n \And (\sim n +1) = n \And (-n)\]
So we put a sequence into \ (log (x) \) between cells,
while(x > 0) {
printf("[%d %d]\n", x - (x & -x) + 1, x);
x -= x & -x;
}
Fenwick tree data structure is based on the above idea, the basic purpose is to maintain a prefix and a sequence. For a given sequence a, we create an array c, where c [x] stored sequence a interval [x - lowbit (x) + 1, x] for all numbers and, and \ (\ sum ^ x_ {x - lowbit (x) + 1} a [i] \)
Then we look at the most basic operations it Fenwick tree
1. Single-point modification, the query interval
Title Description
If that is known to a number of columns, you need to perform the following two operations:
A number x plus 1. The
2. obtaining a number of sections and each
Input Format
The first line contains two integers N, M, respectively, represents the number of the total number of columns and number of operations.
The second line contains N integers separated by spaces, wherein the number indicates the i-th column of the item i of the initial value.
Next M lines contains three integers, it represents one operation, as follows:
Operation 1: Format: 1 XK Meaning: the number of x plus k
Operation 2: Format: 2 XY Meaning: the number of outputs of each interval [x, y] and the
Output Format
Output contains an integer number of lines, that is, the operation results of all 2.
For queries and x is 1 to prefixes, we follow the method just mentioned, it should be determined for each bit in the binary representation of x is equal to 1, the [1, x] into \ (log (n) \) subintervals, and between each cell and have been stored in the array c. So the code above can be rewritten in a little (log (n) \) \ query prefix within the time and:
inline int ask(int x) {
int ans = 0;
for(; x > 0; x -= x & -x) ans += c[x];
return ans;
}
Of course, to query interval [l, r] and all numbers, need only count \ (ask (r) -ask ( l - 1) \)
For single-point change the a number of affects c [x] that is stored in all of its ancestor nodes "section and" including a [x], and any node ancestor Up \ (log (n) \) a, we can be updated individually c value to them.
inline void add(int x, int k) {
for(; x <= n; x += x & -x) c[x] += k;
}
Before all operations, we need to initialize the array tree - a tree-like array of original sequence for a construction
For simplicity, while our initial approach, each reading a a [i], perform add (i, a [i] ) of the operation, the time complexity is \ (O (nlogn) \) , this method has been generally enough.
There is a more efficient way, and directly updated with a prefix manner c [x], the time complexity is \ (O (n-) \) , but this method requires a more open array of prefix and
for(int i = 1; i <= n; ++i) {
read(a[i]);
add(i, a[i]);
}
for(int i = 1; i <= n; ++i) {
read(a[i]);
sum[i] = sum[i - 1] + a[i];
}
for(int i = 1; i <= n; ++i) {
c[i] = sum[i] - sum[i - (i & -i)];
}
2. The range of inquiries, a single point of modification
Title Description
If that is known to a number of columns, you need to perform the following two operations:
1. Each section plus a few number x
Obtaining a value of 2. The number of
Input Format
The first line contains two integers N, M, respectively, represents the number of the total number of columns and number of operations.
The second line contains N integers separated by spaces, wherein the number indicates the i-th column of the item i of the initial value.
Next M lines contains an integer of 2 or 4, it indicates an operation as follows:
Operation 1: Format: 1 XYK Meaning: the interval [x, y] k each number plus
Operation 2: Format: 2 x Meaning: the number of x-value output
Output Format
Output contains an integer number of lines, that is, the operation results of all 2.